/**
 * 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.grapher;

import com.google.common.collect.ImmutableSet;
import com.google.inject.AbstractModule;
import com.google.inject.Binding;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.TypeLiteral;
import com.google.inject.grapher.TransitiveDependencyVisitor;
import com.google.inject.name.Names;
import com.google.inject.spi.ConstructorBinding;
import com.google.inject.spi.ConvertedConstantBinding;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.HasDependencies;
import com.google.inject.spi.InstanceBinding;
import com.google.inject.spi.LinkedKeyBinding;
import com.google.inject.spi.ProviderBinding;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderKeyBinding;

import java.util.Collection;
import java.util.Set;

import junit.framework.TestCase;

/**
 * Tests for {@link TransitiveDependencyVisitor}.
 *
 * @author phopkins@gmail.com (Pete Hopkins)
 */
public class TransitiveDependencyVisitorTest extends TestCase {
  private TransitiveDependencyVisitor visitor;
  
  @Override
  protected void setUp() throws Exception {
    super.setUp();
    
    visitor = new TransitiveDependencyVisitor();
  }

  public void testVisitConstructor() {
    Binding<?> binding = getBinding(Key.get(ConstructedClass.class));
    Collection<Key<?>> dependencies = visitor.visitConstructor((ConstructorBinding<?>) binding);
    
    assertDependencies(dependencies, Key.get(A.class), Key.get(B.class), Key.get(C.class),
        Key.get(D.class));
  }

  public void testVisitConvertedConstant() {
    Binding<?> binding = getBinding(Key.get(Integer.class, Names.named("number")),
        new ConvertedConstantModule());
    Collection<Key<?>> dependencies = visitor.visitConvertedConstant(
        (ConvertedConstantBinding<?>) binding);
    
    assertDependencies(dependencies, Key.get(String.class, Names.named("number")));
  }

  public void testVisitInstance() {
    Binding<?> binding = getBinding(Key.get(ConstructedClass.class), new InstanceModule());
    Collection<Key<?>> dependencies = visitor.visitInstance(
        (InstanceBinding<?>) binding);
    
    // Dependencies will only be on the field- and method-injected classes.
    assertDependencies(dependencies, Key.get(A.class), Key.get(D.class));
  }

  public void testVisitLinkedKey() {
    Binding<?> binding = getBinding(Key.get(Interface.class), new LinkedKeyModule());
    Collection<Key<?>> dependencies = visitor.visitLinkedKey((LinkedKeyBinding<?>) binding);

    // Dependency should be to the class this interface is bound to.
    assertDependencies(dependencies, Key.get(ConstructedClass.class));
  }

  public void testVisitProviderBinding() {
    Binding<?> binding = getBinding(Key.get(new TypeLiteral<Provider<ConstructedClass>>() {}));
    Collection<Key<?>> dependencies = visitor.visitProviderBinding((ProviderBinding<?>) binding);
    
    assertDependencies(dependencies, Key.get(ConstructedClass.class));
  }

  public void testVisitProviderInstance() {
    Binding<?> binding = getBinding(Key.get(ConstructedClass.class),
        new ProviderInstanceModule());
    Collection<Key<?>> dependencies = visitor.visitProviderInstance(
        (ProviderInstanceBinding<?>) binding);
    
    // Dependencies will only be on the field- and method-injected classes.
    assertDependencies(dependencies, Key.get(E.class), Key.get(F.class), Key.get(G.class));
  }

  public void testVisitProviderKey() {
    Binding<?> binding = getBinding(Key.get(ConstructedClass.class), new ProviderKeyModule());
    Collection<Key<?>> dependencies = visitor.visitProviderKey((ProviderKeyBinding<?>) binding);

    // Dependency should be to the class that provides this one.
    assertDependencies(dependencies, Key.get(ConstructedClassProvider.class));
  }
  
  private Binding<?> getBinding(Key<?> key, Module... modules) {
    return Guice.createInjector(modules).getBinding(key);
  }
  
  private void assertDependencies(Collection<Key<?>> dependencies, Key<?>... keys) {
    assertNotNull("Dependencies should not be null", dependencies);
    assertEquals("There should be " + keys.length + " dependencies",
        keys.length, dependencies.size());

    for (Key<?> key : keys) {
      assertTrue("Dependencies should contain " + key, dependencies.contains(key));
    }
  }

  private static class A {}
  private static class B {}
  private static class C {}
  private static class D {}
  private static class E {}
  private static class F {}
  private static class G {}
  
  private static interface Interface {}
  
  private static class ConstructedClass implements Interface {
    @Inject A a;
    ConstructedClass() {}
    @Inject ConstructedClass(B b, C c) {}
    @Inject void setD(D d) {}
  }

  private static class ConstructedClassProvider
  implements Provider<ConstructedClass>, HasDependencies {
    @Inject E e;
    ConstructedClassProvider() {}
    @Inject ConstructedClassProvider(A a, B b, C c) {}
    @Inject void setF(F f) {}
    
    public ConstructedClass get() {
      return null;
    }

    public Set<Dependency<?>> getDependencies() {
      return ImmutableSet.<Dependency<?>>of(Dependency.get(Key.get(G.class)));
    }
  }
  
  private static class ConvertedConstantModule extends AbstractModule {
    @Override
    protected void configure() {
      bindConstant().annotatedWith(Names.named("number")).to("2008");
    }
  }

  private static class InstanceModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(ConstructedClass.class).toInstance(new ConstructedClass());
    }
  }

  private static class LinkedKeyModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(Interface.class).to(ConstructedClass.class);
    }
  }
  
  private static class ProviderInstanceModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(ConstructedClass.class).toProvider(new ConstructedClassProvider());
    }
  }
  
  private static class ProviderKeyModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(ConstructedClass.class).toProvider(ConstructedClassProvider.class);
    }
  }
}
