/**
 * Copyright (C) 2010 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.assistedinject;

import static com.google.inject.name.Names.named;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.AbstractModule;
import com.google.inject.Binding;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Stage;
import com.google.inject.name.Named;
import com.google.inject.spi.DefaultBindingTargetVisitor;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.Element;
import com.google.inject.spi.Elements;

import junit.framework.AssertionFailedError;
import junit.framework.TestCase;

import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

/**
 * Tests for AssistedInject Spi.
 *
 * @author ramakrishna@google.com (Ramakrishna Rajanna)
 */
public class ExtensionSpiTest extends TestCase {

  public final void testSpiOnElements() throws Exception {
    AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor();
    Integer count = 0;
    for(Element element : Elements.getElements(new Module())) {
      if(element instanceof Binding) {
        assertEquals(count++, ((Binding<?>)element).acceptTargetVisitor(visitor));
      }
    }
    validateVisitor(visitor);
  }

  public void testSpiOnVisitor() throws Exception {
    AssistedInjectSpiVisitor visitor = new AssistedInjectSpiVisitor();
    Integer count = 0;
    Injector injector = Guice.createInjector(new Module());
    for(Binding<?> binding : injector.getBindings().values()) {
      assertEquals(count++, binding.acceptTargetVisitor(visitor));
    }
    validateVisitor(visitor);
  }

  private void validateVisitor(AssistedInjectSpiVisitor visitor) throws Exception {
    assertEquals(1, visitor.assistedBindingCount);
    List<AssistedMethod> assistedMethods =
        Lists.newArrayList(Iterables.getOnlyElement(
            visitor.assistedInjectBindings).getAssistedMethods());
    assertEquals(7, assistedMethods.size());
    assertEquals(1, visitor.assistedBindingCount);
    assertEquals(1, visitor.assistedInjectBindings.size());

    // Validate for each of the methods in AnimalFactory
    validateCreateAStrangeCatAsAnimal(assistedMethods.get(0));
    validatecreateStrangeCatWithConstructorForOwner(assistedMethods.get(1));
    validatecreateStrangeCatWithConstructorForAge(assistedMethods.get(2));
    validateCreateCatWithANonAssistedDependency(assistedMethods.get(3));
    validateCreateCat(assistedMethods.get(4));
    validateCreateASimpleCatAsAnimal(assistedMethods.get(5));
    validateCreateCatWithNonAssistedDependencies(assistedMethods.get(6));

  }

  private void validateCreateAStrangeCatAsAnimal(AssistedMethod assistedMethod) {
    validateAssistedMethod(assistedMethod, "createAStrangeCatAsAnimal",
      StrangeCat.class, ImmutableList.<Key<?>>of());
  }

  private void validatecreateStrangeCatWithConstructorForOwner(AssistedMethod assistedMethod) {
    validateAssistedMethod(assistedMethod, "createStrangeCatWithConstructorForOwner",
      StrangeCat.class, ImmutableList.<Key<?>>of());
  }

  private void validatecreateStrangeCatWithConstructorForAge(AssistedMethod assistedMethod) {
    validateAssistedMethod(assistedMethod, "createStrangeCatWithConstructorForAge",
      StrangeCat.class, ImmutableList.<Key<?>>of());
  }

  private void validateCreateCatWithANonAssistedDependency(AssistedMethod assistedMethod)
      throws Exception {
    validateAssistedMethod(assistedMethod, "createCatWithANonAssistedDependency",
        CatWithAName.class, ImmutableList.<Key<?>>of(Key.get(String.class, named("catName2"))));
  }

  private void validateCreateCat(AssistedMethod assistedMethod) throws Exception {
    validateAssistedMethod(assistedMethod, "createCat", Cat.class, ImmutableList.<Key<?>>of());
  }

  private void validateCreateASimpleCatAsAnimal(AssistedMethod assistedMethod) {
    validateAssistedMethod(assistedMethod, "createASimpleCatAsAnimal", SimpleCat.class,
        ImmutableList.<Key<?>>of());
  }

  private void validateCreateCatWithNonAssistedDependencies(AssistedMethod assistedMethod) {
    List<Key<?>> dependencyKeys = ImmutableList.<Key<?>>of(
        Key.get(String.class, named("catName1")),
        Key.get(String.class, named("petName")),        
        Key.get(Integer.class, named("age")));
    validateAssistedMethod(assistedMethod, "createCatWithNonAssistedDependencies",
      ExplodingCat.class, dependencyKeys);
  }

  private void validateAssistedMethod(AssistedMethod assistedMethod, String factoryMethodName,
                                      Class clazz, List<Key<?>> dependencyKeys){
    assertEquals(factoryMethodName, assistedMethod.getFactoryMethod().getName());
    assertEquals(clazz, assistedMethod.getImplementationConstructor().getDeclaringClass());
    assertEquals(dependencyKeys.size(), assistedMethod.getDependencies().size());
    for (Dependency<?> dependency : assistedMethod.getDependencies()) {
      assertTrue(dependencyKeys.contains(dependency.getKey()));
    }
    assertEquals(clazz, assistedMethod.getImplementationType().getType());
  }


  interface AnimalFactory {
    Cat createCat(String owner);
    CatWithAName createCatWithANonAssistedDependency(String owner);
    @Named("SimpleCat") Animal createASimpleCatAsAnimal(String owner);
    Animal createAStrangeCatAsAnimal(String owner);
    StrangeCat createStrangeCatWithConstructorForOwner(String owner);
    StrangeCat createStrangeCatWithConstructorForAge(Integer age);
    ExplodingCat createCatWithNonAssistedDependencies(String owner);
  }

  interface Animal {}

  private static class Cat implements Animal {
    @Inject Cat(@Assisted String owner) {}
  }

  private static class SimpleCat implements Animal {
    @Inject SimpleCat(@Assisted String owner) {
    }
  }

  private static class StrangeCat implements Animal {
    @AssistedInject StrangeCat(@Assisted String owner) {}
    @AssistedInject StrangeCat(@Assisted Integer age) {}
  }

  private static class ExplodingCat implements Animal {
    @Inject public ExplodingCat(@Named("catName1") String name, @Assisted String owner,
                                @Named("age") Integer age, @Named("petName") String petName) {}
  }

  private static class CatWithAName extends Cat {
    @Inject CatWithAName(@Assisted String owner, @Named("catName2") String name) {
      super(owner);
    }
  }

  public class Module extends AbstractModule{
    @Override
    protected void configure() {
      bind(String.class).annotatedWith(named("catName1")).toInstance("kitty1");
      bind(String.class).annotatedWith(named("catName2")).toInstance("kitty2");
      bind(String.class).annotatedWith(named("petName")).toInstance("pussy");
      bind(Integer.class).annotatedWith(named("age")).toInstance(12);
      install(new FactoryModuleBuilder()
        .implement(Animal.class, StrangeCat.class)
        .implement(Animal.class, named("SimpleCat"), SimpleCat.class)
        .build(AnimalFactory.class));
    }
  }

  public class AssistedInjectSpiVisitor extends DefaultBindingTargetVisitor<Object, Integer>
      implements AssistedInjectTargetVisitor<Object, Integer>  {

    private final Set<Class> allowedClasses = 
      ImmutableSet.<Class> of(
        Injector.class, Stage.class, Logger.class,
        String.class, Integer.class);
    
    private int assistedBindingCount = 0;
    private int currentCount = 0;
    private List<AssistedInjectBinding<?>> assistedInjectBindings = Lists.newArrayList();

    public Integer visit(AssistedInjectBinding assistedInjectBinding) {
      assistedInjectBindings.add(assistedInjectBinding);
      assistedBindingCount++;
      return currentCount++;
    }

    @Override
    protected Integer visitOther(Binding<? extends Object> binding) {
      if(!allowedClasses.contains(binding.getKey().getTypeLiteral().getRawType())) {
        throw new AssertionFailedError("invalid other binding: " + binding);
      }
      return currentCount++;
    }
  }
}
