/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.inject;

import static com.google.inject.Asserts.assertContains;

import com.google.inject.name.Named;
import com.google.inject.name.Names;
import junit.framework.TestCase;

/**
 * This test verifies the ways things are injected (ie. getInstance(), injectMembers(), bind to
 * instance, and bind to provider instance) for all states of optional bindings (fields, methods,
 * multiple-argument methods, provider fields, provider methods, constructors).
 *
 * @author jessewilson@google.com (Jesse Wilson)
 */
public class OptionalBindingTest extends TestCase {

  private static final A injectA = new A() {};
  private static final B injectB = new B() {};
  private static final C injectC = new C() {};
  private static final D injectD = new D() {};
  private static final E injectE = new E() {};
  private static final F injectF = new F() {};
  private static final G injectG = new G() {};

  private Module everythingModule =
      new AbstractModule() {
        @Override
        protected void configure() {
          bind(A.class).toInstance(injectA);
          bind(B.class).toInstance(injectB);
          bind(C.class).toInstance(injectC);
          bind(D.class).toInstance(injectD);
          bind(E.class).annotatedWith(Names.named("e")).toInstance(injectE);
          bind(F.class).toInstance(injectF);
          bind(G.class).toInstance(injectG);
        }
      };

  private Module partialModule =
      new AbstractModule() {
        @Override
        protected void configure() {
          bind(C.class).toInstance(new C() {});
        }
      };

  private Module toInstanceModule =
      new AbstractModule() {
        @Override
        protected void configure() {
          bind(HasOptionalInjections.class).toInstance(new HasOptionalInjections());
        }
      };

  private Module toProviderInstanceModule =
      new AbstractModule() {
        @Override
        protected void configure() {
          bind(HasOptionalInjections.class).toProvider(new HasOptionalInjectionsProvider());
        }
      };

  private Module toProviderModule =
      new AbstractModule() {
        @Override
        protected void configure() {
          bind(HasOptionalInjections.class).toProvider(HasOptionalInjectionsProvider.class);
        }
      };

  public void testEverythingInjectorGetInstance() {
    Guice.createInjector(everythingModule)
        .getInstance(HasOptionalInjections.class)
        .assertEverythingInjected();
  }

  public void testPartialInjectorGetInstance() {
    Guice.createInjector(partialModule)
        .getInstance(HasOptionalInjections.class)
        .assertNothingInjected();
  }

  public void testNothingInjectorGetInstance() {
    Guice.createInjector().getInstance(HasOptionalInjections.class).assertNothingInjected();
  }

  public void testEverythingInjectorInjectMembers() {
    HasOptionalInjections instance = new HasOptionalInjections();
    Guice.createInjector(everythingModule).injectMembers(instance);
    instance.assertEverythingInjected();
  }

  public void testPartialInjectorInjectMembers() {
    HasOptionalInjections instance = new HasOptionalInjections();
    Guice.createInjector(partialModule).injectMembers(instance);
    instance.assertNothingInjected();
  }

  public void testNothingInjectorInjectMembers() {
    HasOptionalInjections instance = new HasOptionalInjections();
    Guice.createInjector().injectMembers(instance);
    instance.assertNothingInjected();
  }

  public void testEverythingInjectorToInstance() {
    Guice.createInjector(everythingModule, toInstanceModule)
        .getInstance(HasOptionalInjections.class)
        .assertEverythingInjected();
  }

  public void testPartialInjectorToInstance() {
    Guice.createInjector(partialModule, toInstanceModule)
        .getInstance(HasOptionalInjections.class)
        .assertNothingInjected();
  }

  public void testNothingInjectorToInstance() {
    Guice.createInjector(toInstanceModule)
        .getInstance(HasOptionalInjections.class)
        .assertNothingInjected();
  }

  public void testEverythingInjectorToProviderInstance() {
    Guice.createInjector(everythingModule, toProviderInstanceModule)
        .getInstance(HasOptionalInjections.class)
        .assertEverythingInjected();
  }

  public void testPartialInjectorToProviderInstance() {
    Guice.createInjector(partialModule, toProviderInstanceModule)
        .getInstance(HasOptionalInjections.class)
        .assertNothingInjected();
  }

  public void testNothingInjectorToProviderInstance() {
    Guice.createInjector(toProviderInstanceModule)
        .getInstance(HasOptionalInjections.class)
        .assertNothingInjected();
  }

  public void testEverythingInjectorToProvider() {
    Guice.createInjector(everythingModule, toProviderModule)
        .getInstance(HasOptionalInjections.class)
        .assertEverythingInjected();
  }

  public void testPartialInjectorToProvider() {
    Guice.createInjector(partialModule, toProviderModule)
        .getInstance(HasOptionalInjections.class)
        .assertNothingInjected();
  }

  public void testNothingInjectorToProvider() {
    Guice.createInjector(toProviderModule)
        .getInstance(HasOptionalInjections.class)
        .assertNothingInjected();
  }

  static class HasOptionalInjections {
    A originalA = new A() {};

    @Inject(optional = true)
    A a = originalA; // field injection

    B b; // method injection with one argument
    C c; // method injection with two arguments
    D d; // method injection with two arguments
    E e; // annotated injection

    @Inject(optional = true)
    Provider<F> fProvider; // provider

    Provider<G> gProvider; // method injection of provider
    boolean invoked0, invoked1, invoked2, invokedAnnotated, invokeProvider;

    @Inject(optional = true)
    void methodInjectZeroArguments() {
      invoked0 = true;
    }

    @Inject(optional = true)
    void methodInjectOneArgument(B b) {
      this.b = b;
      invoked1 = true;
    }

    @Inject(optional = true)
    void methodInjectTwoArguments(C c, D d) {
      this.c = c;
      this.d = d;
      invoked2 = true;
    }

    @Inject(optional = true)
    void methodInjectAnnotated(@Named("e") E e) {
      this.e = e;
      invokedAnnotated = true;
    }

    @Inject(optional = true)
    void methodInjectProvider(Provider<G> gProvider) {
      this.gProvider = gProvider;
      invokeProvider = true;
    }

    void assertNothingInjected() {
      assertSame(originalA, a);
      assertNull(b);
      assertNull(c);
      assertNull(d);
      assertNull(e);
      assertNull(fProvider);
      assertNull(gProvider);
      assertTrue(invoked0);
      assertFalse(invoked1);
      assertFalse(invoked2);
      assertFalse(invokedAnnotated);
    }

    public void assertEverythingInjected() {
      assertNotSame(injectA, originalA);
      assertSame(injectA, a);
      assertSame(injectB, b);
      assertSame(injectC, c);
      assertSame(injectD, d);
      assertSame(injectE, e);
      assertSame(injectF, fProvider.get());
      assertSame(injectG, gProvider.get());
      assertTrue(invoked0);
      assertTrue(invoked1);
      assertTrue(invoked2);
      assertTrue(invokedAnnotated);
    }
  }

  static class HasOptionalInjectionsProvider extends HasOptionalInjections
      implements Provider<HasOptionalInjections> {
    @Override
    public HasOptionalInjections get() {
      return this;
    }
  }

  public void testOptionalConstructorBlowsUp() {
    try {
      Guice.createInjector().getInstance(HasOptionalConstructor.class);
      fail();
    } catch (ConfigurationException expected) {
      assertContains(
          expected.getMessage(),
          "OptionalBindingTest$HasOptionalConstructor.<init>() "
              + "is annotated @Inject(optional=true), but constructors cannot be optional.");
    }
  }

  static class HasOptionalConstructor {
    // Suppress compiler errors by the error-prone checker InjectedConstructorAnnotations,
    // which catches optional injected constructors.
    @SuppressWarnings("InjectedConstructorAnnotations")
    @Inject(optional = true)
    HasOptionalConstructor() {}
  }

  @Inject(optional = true)
  static A staticInjectA;

  public void testStaticInjection() {
    staticInjectA = injectA;
    Guice.createInjector(
        new AbstractModule() {
          @Override
          protected void configure() {
            requestStaticInjection(OptionalBindingTest.class);
          }
        });
    assertSame(staticInjectA, injectA);
  }

  /**
   * Test for bug 107, where we weren't doing optional injection properly for indirect injections.
   */
  public void testIndirectOptionalInjection() {
    Indirect indirect = Guice.createInjector().getInstance(Indirect.class);
    assertNotNull(indirect.hasOptionalInjections);
    indirect.hasOptionalInjections.assertNothingInjected();
  }

  static class Indirect {
    @Inject HasOptionalInjections hasOptionalInjections;
  }

  interface A {}

  interface B {}

  interface C {}

  interface D {}

  interface E {}

  interface F {}

  interface G {}
}
