/**
 * 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 testVisitInstance_instanceHasDependencies() {
    Binding<?> binding = getBinding(Key.get(Interface.class), new HasDependenciesModule());
    Collection<Key<?>> dependencies = visitor.visitInstance(
        (InstanceBinding<?>) binding);
    
    // Dependencies should only be on the stated
    // HasDependencies#getDependencies() values
    assertDependencies(dependencies, Key.get(G.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));
  }

  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> {
    @Inject E e;
    ConstructedClassProvider() {}
    @Inject ConstructedClassProvider(A a, B b, C c) {}
    @Inject void setF(F f) {}
    
    public ConstructedClass get() {
      return null;
    }
  }

  private static class HasDependenciesClass implements Interface, HasDependencies {
    @Inject A a;
    @Inject B b;
    
    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 HasDependenciesModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(Interface.class).toInstance(new HasDependenciesClass());
    }
  }
  
  private static class ProviderKeyModule extends AbstractModule {
    @Override
    protected void configure() {
      bind(ConstructedClass.class).toProvider(ConstructedClassProvider.class);
    }
  }
}
