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

import com.google.inject.AbstractModule;
import static com.google.inject.Asserts.assertContains;
import com.google.inject.Binding;
import com.google.inject.BindingAnnotation;
import com.google.inject.Inject;
import com.google.inject.Key;
import com.google.inject.MembersInjector;
import com.google.inject.Module;
import com.google.inject.PrivateBinder;
import com.google.inject.Provider;
import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.Stage;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.AnnotatedBindingBuilder;
import com.google.inject.binder.AnnotatedConstantBindingBuilder;
import com.google.inject.binder.ConstantBindingBuilder;
import com.google.inject.binder.ScopedBindingBuilder;
import com.google.inject.internal.util.ImmutableMap;
import com.google.inject.internal.util.ImmutableSet;
import static com.google.inject.internal.util.Iterables.getOnlyElement;

import com.google.inject.matcher.Matcher;
import com.google.inject.matcher.Matchers;
import com.google.inject.name.Named;
import com.google.inject.name.Names;
import com.google.inject.util.Providers;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import junit.framework.TestCase;

/**
 * @author jessewilson@google.com (Jesse Wilson)
 */
public class ElementsTest extends TestCase {

  // Binder fidelity tests

  public void testAddMessageErrorCommand() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            addError("Message %s %d %s", "A", 5, "C");
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Message A 5 C", command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSources().toString(),
                ElementsTest.class.getName(), ".configure(ElementsTest.java:");
            assertContains(command.getSource(), "ElementsTest.java");
            return null;
          }
        }
    );
  }

  public void testAddThrowableErrorCommand() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            addError(new Exception("A"));
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("A", command.getCause().getMessage());
            assertEquals(command.getMessage(),
                "An exception was caught and reported. Message: A");
            assertContains(command.getSource(), "ElementsTest.java");
            return null;
          }
        }
    );
  }

  public void testErrorsAddedWhenExceptionsAreThrown() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            install(new AbstractModule() {
              protected void configure() {
                throw new RuntimeException("Throwing RuntimeException in AbstractModule.configure().");
              }
            });

            addError("Code after the exception still gets executed");
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Throwing RuntimeException in AbstractModule.configure().",
                command.getCause().getMessage());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Code after the exception still gets executed",
                command.getMessage());
            return null;
          }
        }
    );
  }

  private <T> T getInstance(Binding<T> binding) {
    return binding.acceptTargetVisitor(Elements.<T>getInstanceVisitor());
  }

  public void testBindConstantAnnotations() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindConstant().annotatedWith(SampleAnnotation.class).to("A");
            bindConstant().annotatedWith(Names.named("Bee")).to("B");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
            assertEquals("A", getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class, Names.named("Bee")), command.getKey());
            assertEquals("B", getInstance(command));
            return null;
          }
        }
    );
  }

  public void testBindConstantTypes() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindConstant().annotatedWith(Names.named("String")).to("A");
            bindConstant().annotatedWith(Names.named("int")).to(2);
            bindConstant().annotatedWith(Names.named("long")).to(3L);
            bindConstant().annotatedWith(Names.named("boolean")).to(false);
            bindConstant().annotatedWith(Names.named("double")).to(5.0d);
            bindConstant().annotatedWith(Names.named("float")).to(6.0f);
            bindConstant().annotatedWith(Names.named("short")).to((short) 7);
            bindConstant().annotatedWith(Names.named("char")).to('h');
            bindConstant().annotatedWith(Names.named("Class")).to(Iterator.class);
            bindConstant().annotatedWith(Names.named("Enum")).to(CoinSide.TAILS);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class, Names.named("String")), command.getKey());
            assertEquals("A", getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Integer.class, Names.named("int")), command.getKey());
            assertEquals(2, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Long.class, Names.named("long")), command.getKey());
            assertEquals(3L, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Boolean.class, Names.named("boolean")), command.getKey());
            assertEquals(false, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Double.class, Names.named("double")), command.getKey());
            assertEquals(5.0d, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Float.class, Names.named("float")), command.getKey());
            assertEquals(6.0f, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Short.class, Names.named("short")), command.getKey());
            assertEquals((short) 7, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Character.class, Names.named("char")), command.getKey());
            assertEquals('h', getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(Class.class, Names.named("Class")), command.getKey());
            assertEquals(Iterator.class, getInstance(command));
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(CoinSide.class, Names.named("Enum")), command.getKey());
            assertEquals(CoinSide.TAILS, getInstance(command));
            return null;
          }
        }
    );
  }

  public void testBindKeysNoAnnotations() {
    FailingElementVisitor keyChecker = new FailingElementVisitor() {
      @Override public <T> Void visit(Binding<T> command) {
        assertEquals(Key.get(String.class), command.getKey());
        return null;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toInstance("A");
            bind(new TypeLiteral<String>() {}).toInstance("B");
            bind(Key.get(String.class)).toInstance("C");
          }
        },
        keyChecker,
        keyChecker,
        keyChecker
    );
  }

  public void testBindKeysWithAnnotationType() {
    FailingElementVisitor annotationChecker = new FailingElementVisitor() {
      @Override public <T> Void visit(Binding<T> command) {
        assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
        return null;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).annotatedWith(SampleAnnotation.class).toInstance("A");
            bind(new TypeLiteral<String>() {}).annotatedWith(SampleAnnotation.class).toInstance("B");
          }
        },
        annotationChecker,
        annotationChecker
    );
  }

  public void testBindKeysWithAnnotationInstance() {
    FailingElementVisitor annotationChecker = new FailingElementVisitor() {
      @Override public <T> Void visit(Binding<T> command) {
        assertEquals(Key.get(String.class, Names.named("a")), command.getKey());
        return null;
      }
    };


    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).annotatedWith(Names.named("a")).toInstance("B");
            bind(new TypeLiteral<String>() {}).annotatedWith(Names.named("a")).toInstance("C");
          }
        },
        annotationChecker,
        annotationChecker
    );
  }

  public void testBindToProvider() {
    final Provider<String> aProvider = new Provider<String>() {
      public String get() {
        return "A";
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toProvider(aProvider);
            bind(List.class).toProvider(ListProvider.class);
            bind(Collection.class).toProvider(Key.get(ListProvider.class));
            bind(Iterable.class).toProvider(new TypeLiteral<TProvider<List>>() {});
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof ProviderInstanceBinding);
            assertEquals(Key.get(String.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(
                  ProviderInstanceBinding<? extends T> binding) {
                assertSame(aProvider, binding.getProviderInstance());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof ProviderKeyBinding);
            assertEquals(Key.get(List.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
                assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof ProviderKeyBinding);
            assertEquals(Key.get(Collection.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
                assertEquals(Key.get(ListProvider.class), binding.getProviderKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof ProviderKeyBinding);
            assertEquals(Key.get(Iterable.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ProviderKeyBinding<? extends T> binding) {
                assertEquals(new Key<TProvider<List>>() {}, binding.getProviderKey());
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToLinkedBinding() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(List.class).to(ArrayList.class);
            bind(Map.class).to(new TypeLiteral<HashMap<Integer, String>>() {});
            bind(Set.class).to(Key.get(TreeSet.class, SampleAnnotation.class));
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof LinkedKeyBinding);
            assertEquals(Key.get(List.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
                assertEquals(Key.get(ArrayList.class), binding.getLinkedKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof LinkedKeyBinding);
            assertEquals(Key.get(Map.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
                assertEquals(Key.get(new TypeLiteral<HashMap<Integer, String>>() {}),
                    binding.getLinkedKey());
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof LinkedKeyBinding);
            assertEquals(Key.get(Set.class), command.getKey());
            command.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(LinkedKeyBinding<? extends T> binding) {
                assertEquals(Key.get(TreeSet.class, SampleAnnotation.class),
                    binding.getLinkedKey());
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToInstance() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toInstance("A");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertTrue(command instanceof InstanceBinding);
            assertEquals(Key.get(String.class), command.getKey());
            assertEquals("A", getInstance(command));
            return null;
          }
        }
    );
  }

  public void testBindInScopes() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class);
            bind(List.class).to(ArrayList.class).in(Scopes.SINGLETON);
            bind(Map.class).to(HashMap.class).in(Singleton.class);
            bind(Set.class).to(TreeSet.class).asEagerSingleton();
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertEquals(Key.get(String.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitNoScoping() {
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertEquals(Key.get(List.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitScope(Scope scope) {
                assertEquals(Scopes.SINGLETON, scope);
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertEquals(Key.get(Map.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
                assertEquals(Singleton.class, annotation);
                return null;
              }
            });
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            assertEquals(Key.get(Set.class), command.getKey());
            command.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              public Void visitEagerSingleton() {
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToInstanceInScope() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedBindingBuilder<String> b = bind(String.class);
            b.toInstance("A");
            b.in(Singleton.class);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Setting the scope is not permitted when binding to a single instance.",
                command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), "ElementsTest.java");
            return null;
          }
        }
      );
  }

  public void testBindToInstanceScope() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(String.class).toInstance("A");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> binding) {
            assertEquals(Key.get(String.class), binding.getKey());
            binding.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              public Void visitEagerSingleton() {
                return null;
              }
            });
            return null;
          }
        }
      );
  }

  /*if[AOP]*/
  public void testBindIntercepor() {
    final Matcher<Class> classMatcher = Matchers.subclassesOf(List.class);
    final Matcher<Object> methodMatcher = Matchers.any();
    final org.aopalliance.intercept.MethodInterceptor methodInterceptor
        = new org.aopalliance.intercept.MethodInterceptor() {
      public Object invoke(org.aopalliance.intercept.MethodInvocation methodInvocation) {
        return null;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindInterceptor(classMatcher, methodMatcher, methodInterceptor);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(InterceptorBinding command) {
            assertSame(classMatcher, command.getClassMatcher());
            assertSame(methodMatcher, command.getMethodMatcher());
            assertEquals(Arrays.asList(methodInterceptor), command.getInterceptors());
            return null;
          }
        }
    );
  }
  /*end[AOP]*/

  public void testBindScope() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindScope(SampleAnnotation.class, Scopes.NO_SCOPE);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(ScopeBinding command) {
            assertSame(SampleAnnotation.class, command.getAnnotationType());
            assertSame(Scopes.NO_SCOPE, command.getScope());
            return null;
          }
        }
    );
  }

  public void testBindListener() {
    final Matcher<Object> typeMatcher = Matchers.only(TypeLiteral.get(String.class));
    final TypeListener listener = new TypeListener() {
      public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
        throw new UnsupportedOperationException();
      }
    };
    
    checkModule(
        new AbstractModule() {
          protected void configure() {
            bindListener(typeMatcher, listener);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(TypeListenerBinding binding) {
            assertSame(typeMatcher, binding.getTypeMatcher());
            assertSame(listener, binding.getListener());
            return null;
          }
        }
    );
  }

  public void testConvertToTypes() {
    final TypeConverter typeConverter = new TypeConverter() {
      public Object convert(String value, TypeLiteral<?> toType) {
        return value;
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            convertToTypes(Matchers.any(), typeConverter);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(TypeConverterBinding command) {
            assertSame(typeConverter, command.getTypeConverter());
            assertSame(Matchers.any(), command.getTypeMatcher());
            return null;
          }
        }
    );
  }

  public void testGetProvider() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            Provider<String> keyGetProvider
                = getProvider(Key.get(String.class, SampleAnnotation.class));
            try {
              keyGetProvider.get();
            } catch (IllegalStateException e) {
              assertEquals("This Provider cannot be used until the Injector has been created.",
                  e.getMessage());
            }

            Provider<String> typeGetProvider = getProvider(String.class);
            try {
              typeGetProvider.get();
            } catch (IllegalStateException e) {
              assertEquals("This Provider cannot be used until the Injector has been created.",
                  e.getMessage());
            }
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(ProviderLookup<T> command) {
            assertEquals(Key.get(String.class, SampleAnnotation.class), command.getKey());
            assertNull(command.getDelegate());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(ProviderLookup<T> command) {
            assertEquals(Key.get(String.class), command.getKey());
            assertNull(command.getDelegate());
            return null;
          }
        }
    );
  }
  
  public void testElementInitialization() {
    final AtomicReference<Provider<String>> providerFromBinder
        = new AtomicReference<Provider<String>>();
    final AtomicReference<MembersInjector<String>> membersInjectorFromBinder
        = new AtomicReference<MembersInjector<String>>();

    final AtomicReference<String> lastInjected = new AtomicReference<String>();
    final MembersInjector<String> stringInjector = new MembersInjector<String>() {
      public void injectMembers(String instance) {
        lastInjected.set(instance);
      }
    };

    checkModule(
        new AbstractModule() {
          protected void configure() {
            providerFromBinder.set(getProvider(String.class));
            membersInjectorFromBinder.set(getMembersInjector(String.class));
          }
        },

        new FailingElementVisitor() {
          public <T> Void visit(ProviderLookup<T> providerLookup) {
            @SuppressWarnings("unchecked") // we know that T is a String here
            ProviderLookup<String> stringLookup = (ProviderLookup<String>) providerLookup;
            stringLookup.initializeDelegate(Providers.of("out"));

            assertEquals("out", providerFromBinder.get().get());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(MembersInjectorLookup<T> lookup) {
            @SuppressWarnings("unchecked") // we know that T is a String here
            MembersInjectorLookup<String> stringLookup = (MembersInjectorLookup<String>) lookup;
            stringLookup.initializeDelegate(stringInjector);

            membersInjectorFromBinder.get().injectMembers("in");
            assertEquals("in", lastInjected.get());
            return null;
          }
        });
  }

  public void testGetMembersInjector() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            MembersInjector<A<String>> typeMembersInjector
                = getMembersInjector(new TypeLiteral<A<String>>() {});
            try {
              typeMembersInjector.injectMembers(new A<String>());
            } catch (IllegalStateException e) {
              assertEquals(
                  "This MembersInjector cannot be used until the Injector has been created.",
                  e.getMessage());
            }

            MembersInjector<String> classMembersInjector = getMembersInjector(String.class);
            try {
              classMembersInjector.injectMembers("hello");
            } catch (IllegalStateException e) {
              assertEquals(
                  "This MembersInjector cannot be used until the Injector has been created.",
                  e.getMessage());
            }
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(MembersInjectorLookup<T> command) {
            assertEquals(new TypeLiteral<A<String>>() {}, command.getType());
            assertNull(command.getDelegate());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(MembersInjectorLookup<T> command) {
            assertEquals(TypeLiteral.get(String.class), command.getType());
            assertNull(command.getDelegate());
            return null;
          }
        }
    );
  }

  public void testRequestInjection() {
    final Object firstObject = new Object();
    final Object secondObject = new Object();

    checkModule(
        new AbstractModule() {
          protected void configure() {
            requestInjection(firstObject);
            requestInjection(secondObject);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(InjectionRequest<?> command) {
            assertEquals(firstObject, command.getInstance());
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(InjectionRequest<?> command) {
            assertEquals(secondObject, command.getInstance());
            return null;
          }
        }
    );
  }

  public void testRequestStaticInjection() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            requestStaticInjection(ArrayList.class);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(StaticInjectionRequest command) {
            assertEquals(ArrayList.class, command.getType());
            return null;
          }
        }
    );
  }

  public void testNewPrivateBinder() {
    final Key<Collection> collection = Key.get(Collection.class, SampleAnnotation.class);
    final Key<ArrayList> arrayList = Key.get(ArrayList.class);
    final ImmutableSet<Key<?>> collections = ImmutableSet.<Key<?>>of(arrayList, collection);

    final Key<?> a = Key.get(String.class, Names.named("a"));
    final Key<?> b = Key.get(String.class, Names.named("b"));
    final ImmutableSet<Key<?>> ab = ImmutableSet.of(a, b);

    checkModule(
        new AbstractModule() {
          protected void configure() {
            PrivateBinder one = binder().newPrivateBinder();
            one.expose(ArrayList.class);
            one.expose(Collection.class).annotatedWith(SampleAnnotation.class);
            one.bind(List.class).to(ArrayList.class);

            PrivateBinder two = binder().withSource("1 ElementsTest.java")
                .newPrivateBinder().withSource("2 ElementsTest.java");
            two.expose(String.class).annotatedWith(Names.named("a"));
            two.expose(b);
            two.bind(List.class).to(ArrayList.class);
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(PrivateElements one) {
            assertEquals(collections, one.getExposedKeys());
            checkElements(one.getElements(),
                new FailingElementVisitor() {
                  @Override public <T> Void visit(Binding<T> binding) {
                    assertEquals(Key.get(List.class), binding.getKey());
                    return null;
                  }
                }
            );
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(PrivateElements two) {
            assertEquals(ab, two.getExposedKeys());
            assertEquals("1 ElementsTest.java", two.getSource());
            checkElements(two.getElements(),
                new FailingElementVisitor() {
                  @Override public <T> Void visit(Binding<T> binding) {
                    assertEquals("2 ElementsTest.java", binding.getSource());
                    assertEquals(Key.get(List.class), binding.getKey());
                    return null;
                  }
                }
            );
            return null;
          }
        }
    );
  }

  public void testBindWithMultipleAnnotationsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedBindingBuilder<String> abb = bind(String.class);
            abb.annotatedWith(SampleAnnotation.class);
            abb.annotatedWith(Names.named("A"));
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("More than one annotation is specified for this binding.",
                command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), "ElementsTest.java");
            return null;
          }
        }
    );
  }

  public void testBindWithMultipleTargetsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedBindingBuilder<String> abb = bind(String.class);
            abb.toInstance("A");
            abb.toInstance("B");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Implementation is set more than once.", command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), "ElementsTest.java");
            return null;
          }
        }
    );
  }

  public void testBindWithMultipleScopesAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            ScopedBindingBuilder sbb = bind(List.class).to(ArrayList.class);
            sbb.in(Scopes.NO_SCOPE);
            sbb.asEagerSingleton();
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("Scope is set more than once.", command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), "ElementsTest.java");
            return null;
          }
        }
    );
  }

  public void testBindConstantWithMultipleAnnotationsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            AnnotatedConstantBindingBuilder cbb = bindConstant();
            cbb.annotatedWith(SampleAnnotation.class).to("A");
            cbb.annotatedWith(Names.named("A"));
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message command) {
            assertEquals("More than one annotation is specified for this binding.",
                command.getMessage());
            assertNull(command.getCause());
            assertContains(command.getSource(), "ElementsTest.java");
            return null;
          }
        }
    );
  }

  public void testBindConstantWithMultipleTargetsAddsError() {
    checkModule(
        new AbstractModule() {
          protected void configure() {
            ConstantBindingBuilder cbb = bindConstant().annotatedWith(SampleAnnotation.class);
            cbb.to("A");
            cbb.to("B");
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> command) {
            return null;
          }
        },

        new FailingElementVisitor() {
          @Override public Void visit(Message message) {
            assertEquals("Constant value is set more than once.", message.getMessage());
            assertNull(message.getCause());
            assertContains(message.getSource(), "ElementsTest.java");
            return null;
          }
        }
    );
  }

  public void testBindToConstructor() throws NoSuchMethodException, NoSuchFieldException {
    final Constructor<A> aConstructor = A.class.getDeclaredConstructor();
    final Constructor<B> bConstructor = B.class.getDeclaredConstructor(Object.class);
    final Field field = B.class.getDeclaredField("stage");

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(A.class).toConstructor(aConstructor);
            bind(B.class).toConstructor(bConstructor, new TypeLiteral<B<Integer>>() {})
                .in(Singleton.class);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> binding) {
            assertEquals(new Key<A>() {}, binding.getKey());

            return binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ConstructorBinding<? extends T> constructorBinding) {
                InjectionPoint injectionPoint = constructorBinding.getConstructor();
                assertEquals(aConstructor, injectionPoint.getMember());
                assertEquals(new TypeLiteral<A>() {}, injectionPoint.getDeclaringType());
                return null;
              }
            });
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> binding) {
            assertEquals(new Key<B>() {}, binding.getKey());
            binding.acceptScopingVisitor(new FailingBindingScopingVisitor() {
              @Override public Void visitScopeAnnotation(Class<? extends Annotation> annotation) {
                assertEquals(Singleton.class, annotation);
                return null;
              }
            });

            binding.acceptTargetVisitor(new FailingTargetVisitor<T>() {
              @Override public Void visit(ConstructorBinding<? extends T> constructorBinding) {
                assertEquals(bConstructor, constructorBinding.getConstructor().getMember());
                assertEquals(Key.get(Integer.class),
                    getOnlyElement(constructorBinding.getConstructor().getDependencies()).getKey());
                assertEquals(field,
                    getOnlyElement(constructorBinding.getInjectableMembers()).getMember());
                assertEquals(2, constructorBinding.getDependencies().size());
                assertEquals(ImmutableMap.of(), constructorBinding.getMethodInterceptors());
                return null;
              }
            });
            return null;
          }
        }
    );
  }

  public void testBindToMalformedConstructor() throws NoSuchMethodException, NoSuchFieldException {
    final Constructor<C> constructor = C.class.getDeclaredConstructor(Integer.class);

    checkModule(
        new AbstractModule() {
          protected void configure() {
            bind(C.class).toConstructor(constructor);
          }
        },

        new FailingElementVisitor() {
          @Override public <T> Void visit(Binding<T> binding) {
            assertEquals(Key.get(C.class), binding.getKey());
            assertTrue(binding instanceof UntargettedBinding);
            return null;
          }
        },

        new ExternalFailureVisitor() {
          @Override public Void visit(Message message) {
            assertContains(message.getMessage(),
                C.class.getName() + ".a has more than one annotation ",
                Named.class.getName(), SampleAnnotation.class.getName());
            return null;
          }
        },

        new ExternalFailureVisitor() {
          @Override public Void visit(Message message) {
            assertContains(message.getMessage(),
                C.class.getName() + ".<init>() has more than one annotation ",
                Named.class.getName(), SampleAnnotation.class.getName());
            return null;
          }
        }
    );
  }

  // Business logic tests

  public void testModulesAreInstalledAtMostOnce() {
    final AtomicInteger aConfigureCount = new AtomicInteger(0);
    final Module a = new AbstractModule() {
      public void configure() {
        aConfigureCount.incrementAndGet();
      }
    };

    Elements.getElements(a, a);
    assertEquals(1, aConfigureCount.get());

    aConfigureCount.set(0);
    Module b = new AbstractModule() {
      protected void configure() {
        install(a);
        install(a);
      }
    };

    Elements.getElements(b);
    assertEquals(1, aConfigureCount.get());
  }


  /**
   * Ensures the module performs the commands consistent with {@code visitors}.
   */
  protected void checkModule(Module module, ElementVisitor<?>... visitors) {
    List<Element> elements = Elements.getElements(module);
    assertEquals(elements.size(), visitors.length);
    checkElements(elements, visitors);
  }

  protected void checkElements(List<Element> elements, ElementVisitor<?>... visitors) {
    for (int i = 0; i < visitors.length; i++) {
      ElementVisitor<?> visitor = visitors[i];
      Element element = elements.get(i);
      if (!(visitor instanceof ExternalFailureVisitor)) {
        assertContains(element.getSource().toString(), "ElementsTest.java");
      }
      element.acceptVisitor(visitor);
    }
  }

  private static class ListProvider implements Provider<List> {
    public List get() {
      return new ArrayList();
    }
  }

  private static class TProvider<T> implements Provider<T> {
    public T get() {
      return null;
    }
  }

  /**
   * By extending this interface rather than FailingElementVisitor, the source of the error doesn't
   * need to contain the string {@code ElementsTest.java}.
   */
  abstract class ExternalFailureVisitor extends FailingElementVisitor {}

  @Retention(RUNTIME)
  @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
  @BindingAnnotation
  public @interface SampleAnnotation { }

  public enum CoinSide { HEADS, TAILS }

  static class A<T> {
    @Inject Stage stage;
  }

  static class B<T> {
    @Inject Stage stage;
    B(T t) {}
  }

  static class C {
    @Inject @Named("foo") @SampleAnnotation String a;
    C(@Named("bar") @SampleAnnotation Integer b) {}
  }
}
