package com.google.inject;

import static com.google.inject.Asserts.assertContains;
import static com.google.inject.internal.util.ImmutableSet.of;

import junit.framework.TestCase;

import java.util.Set;

/**
 * Some tests for {@link InjectorBuilder#requireExplicitBindings()}
 * 
 * @author sberlin@gmail.com (Sam Berlin)
 */
public class JitBindingsTest extends TestCase {
  
  private String jitFailed(Class<?> clazz) {
    return jitFailed(TypeLiteral.get(clazz));
  }
  
  private String jitFailed(TypeLiteral<?> clazz) {
    return "Explicit bindings are required and " + clazz + " is not explicitly bound.";
  }
  
  public void testLinkedBindingWorks() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).to(FooImpl.class);
      }
    }).build();
    // Foo was explicitly bound
    ensureWorks(injector, Foo.class);
    // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
    // It is OK to call getBinding for introspection, but an error to get the provider
    // of the binding
    ensureFails(injector, true, FooImpl.class);
  }
  
  public void testMoreBasicsWork() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).to(FooImpl.class);
        bind(Bar.class);
        bind(FooBar.class);
      }
    }).build();
    // Foo, Bar & FooBar was explicitly bound    
    ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
    // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
    // It is OK to call getBinding for introspection, but an error to get the provider
    // of the binding    
    ensureFails(injector, true,  FooImpl.class);    
  }
  
  public void testLinkedEagerSingleton() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).to(FooImpl.class).asEagerSingleton();
      }
    }).build();
    // Foo was explicitly bound
    ensureWorks(injector, Foo.class);
    // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
    // It is OK to call getBinding for introspection, but an error to get the provider
    // of the binding
    ensureFails(injector, true, FooImpl.class);
  }
  
  public void testBasicsWithEagerSingleton() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).to(FooImpl.class).asEagerSingleton();
        bind(Bar.class);
        bind(FooBar.class);
      }
    }).build();
    // Foo, Bar & FooBar was explicitly bound    
    ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
    // FooImpl was implicitly bound, it is an error to call getInstance or getProvider,
    // It is OK to call getBinding for introspection, but an error to get the provider
    // of the binding    
    ensureFails(injector, true,  FooImpl.class);    
  }  
  
  public void testLinkedToScoped() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).to(ScopedFooImpl.class);
      }
    }).build();
    // Foo was explicitly bound
    ensureWorks(injector, Foo.class);
    // FooSingletonImpl was implicitly bound, it is an error to call getInstance or getProvider,
    // It is OK to call getBinding for introspection, but an error to get the provider
    // of the binding
    ensureFails(injector, true, ScopedFooImpl.class);    
  }
  
  public void testBasicsWithScoped() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).to(ScopedFooImpl.class);
        bind(Bar.class);
        bind(FooBar.class);
      }
    }).build();
    // Foo, Bar & FooBar was explicitly bound    
    ensureWorks(injector, FooBar.class, Bar.class, Foo.class);
    // FooSingletonImpl was implicitly bound, it is an error to call getInstance or getProvider,
    // It is OK to call getBinding for introspection, but an error to get the provider
    // of the binding    
    ensureFails(injector, true,  ScopedFooImpl.class);   
  }
  
  public void testFailsIfInjectingScopedDirectlyWhenItIsntBound() {
    try {
      new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
        @Override
        protected void configure() {
          bind(Foo.class).to(ScopedFooImpl.class);
          bind(WantsScopedFooImpl.class);
        }
      }).build();
      fail();
    } catch(CreationException expected) {
      assertContains(expected.getMessage(), "1) " + jitFailed(ScopedFooImpl.class));
      assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
    }
  }
  
  public void testLinkedProviderBindingWorks() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).toProvider(FooProvider.class);
      }
    }).build();
    // Foo was explicitly bound
    ensureWorks(injector, Foo.class);
    // FooImpl was not bound at all (even implicitly), it is an error
    // to call getInstance, getProvider, or getBinding.
    ensureFails(injector, false, FooImpl.class);
  }
  
  public void testJitGetFails() {
    try {
      new InjectorBuilder().requireExplicitBindings().build().getInstance(Bar.class);
      fail("should have failed");
    } catch(ConfigurationException expected) {
      assertContains(expected.getMessage(), "1) " + jitFailed(Bar.class));
      assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
    }
  }
  
  public void testJitInjectionFails() {
    try {
      new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
        @Override
        protected void configure() {
          bind(Foo.class).to(FooImpl.class);
          bind(FooBar.class);
        }
      }).build();
      fail("should have failed");
    } catch (CreationException expected) {
      assertContains(expected.getMessage(), "1) " + jitFailed(Bar.class));
      assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
    }
  }

  public void testJitProviderGetFails() {
    try {
      new InjectorBuilder().requireExplicitBindings().build().getProvider(Bar.class);
      fail("should have failed");
    } catch (ConfigurationException expected) {
      assertContains(expected.getMessage(), "1) " + jitFailed(Bar.class));
      assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
    }
  }

  public void testJitProviderInjectionFails() {
    try {
      new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
        @Override
        protected void configure() {
          bind(Foo.class).to(FooImpl.class);
          bind(ProviderFooBar.class);
        }
      }).build();
      fail("should have failed");
    } catch (CreationException expected) {
      assertContains(expected.getMessage(), "1) " + jitFailed(Bar.class));
      assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
    }
  }
  
  public void testImplementedBy() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(ImplBy.class);
      }
    }).build();
    ensureWorks(injector, ImplBy.class);
    ensureFails(injector, true, ImplByImpl.class);
  }
  
  public void testImplementedBySomethingThatIsAnnotated() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(ImplByScoped.class);
      }
    }).build();
    ensureWorks(injector, ImplByScoped.class);
    ensureFails(injector, true, ImplByScopedImpl.class);    
  }
  
  public void testProvidedBy() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(ProvBy.class);
      }
    }).build();
    ensureWorks(injector, ProvBy.class);
    ensureFails(injector, true, ProvByProvider.class);
  }
  
  public void testProviderMethods() {
    Injector injector = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override protected void configure() {}
      @SuppressWarnings("unused") @Provides Foo foo() { return new FooImpl(); }
    }).build();
    ensureWorks(injector, Foo.class);
  }
  
  public void testChildInjectors() {
    Injector parent = new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Bar.class);
      }
    }).build();
    ensureWorks(parent, Bar.class);
    ensureFails(parent, false, FooImpl.class, FooBar.class, Foo.class);
    
    try {
      parent.createChildInjector(new AbstractModule() {
        @Override
        protected void configure() {
          bind(FooBar.class);
        }
      });
      fail("should have failed");
    } catch(CreationException expected) {
      assertContains(expected.getMessage(), "1) " + jitFailed(Foo.class));
      assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
    }
    
    Injector child = parent.createChildInjector(new AbstractModule() {
      @Override
      protected void configure() {
        bind(Foo.class).to(FooImpl.class);
      }
    });
    ensureWorks(child, Foo.class, Bar.class);
    ensureFails(child, true, FooImpl.class);
    ensureFails(parent, false, FooImpl.class, FooBar.class, Foo.class); // parent still doesn't have these
    
    Injector grandchild = child.createChildInjector(new AbstractModule() {
      @Override
      protected void configure() {
        bind(FooBar.class);
      }
    });
    ensureWorks(grandchild, FooBar.class, Foo.class, Bar.class);
    ensureFails(grandchild, true, FooImpl.class);
    ensureFails(child, true, FooImpl.class);
    ensureFails(parent, false, FooImpl.class, FooBar.class, Foo.class); // parent still doesn't have these    
  }

  public void testPrivateModules() {
    try {
      new InjectorBuilder().requireExplicitBindings().addModules(new AbstractModule() {
        protected void configure() {
          bind(Foo.class).to(FooImpl.class);
  
          install(new PrivateModule() {
            public void configure() {
              bind(FooBar.class);
              expose(FooBar.class);
            }
          });
        }
      }).build();
      fail("should have failed");
    } catch(CreationException expected) {
      assertContains(expected.getMessage(), "1) " + jitFailed(Bar.class));
      assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
    }
  }
  
  public void testTypeLiteralsCanBeInjected() {
    Injector injector = new InjectorBuilder()
      .requireExplicitBindings()
      .addModules(new AbstractModule() {
        @Override protected void configure() {
          bind(new TypeLiteral<WantsTypeLiterals<String>>() {});
          bind(new TypeLiteral<Set<String>>() {}).toInstance(of("bar"));
        }
      })
      .build();

    WantsTypeLiterals<String> foo = injector.getInstance(new Key<WantsTypeLiterals<String>>() {});
    assertEquals(foo.literal.getRawType(), String.class);
    assertEquals(of("bar"), foo.set);
  }
  
  private void ensureWorks(Injector injector, Class<?>... classes) {
    for(int i = 0; i < classes.length; i++) {
      injector.getInstance(classes[i]);
      injector.getProvider(classes[i]).get();
      injector.getBinding(classes[i]).getProvider().get();
    }
  }
  
  private void ensureFails(Injector injector, boolean allowGetBinding, Class<?>... classes) {
    for(int i = 0; i < classes.length; i++) {      
      try { 
        injector.getInstance(classes[i]);
        fail("should have failed");
      } catch(ConfigurationException expected) {
        assertContains(expected.getMessage(), "1) " + jitFailed(classes[i]));
        assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
      }
      
      try { 
        injector.getProvider(classes[i]);
        fail("should have failed");
      } catch(ConfigurationException expected) {
        assertContains(expected.getMessage(), "1) " + jitFailed(classes[i]));
        assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
      }
      
      if(allowGetBinding) {
        Binding<?> binding = injector.getBinding(classes[i]);
        try {
          binding.getProvider();
          fail("should have failed");
        } catch(ConfigurationException expected) {
          assertContains(expected.getMessage(), "1) " + jitFailed(classes[i]));
          assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
        }
      } else {
        try {
          injector.getBinding(classes[i]);
          fail("should have failed");          
        } catch(ConfigurationException expected) {
          assertContains(expected.getMessage(), "1) " + jitFailed(classes[i]));
          assertTrue(expected.getMessage(), !expected.getMessage().contains("2) "));
        }
      }
    }
  }
  
  private static interface Foo {}
  private static class FooImpl implements Foo {}
  @Singleton private static class ScopedFooImpl implements Foo {}
  private static class WantsScopedFooImpl {
    @SuppressWarnings("unused") @Inject ScopedFooImpl scopedFoo;
  }
  private static class Bar {}
  private static class FooBar {
    @SuppressWarnings("unused") @Inject Foo foo;
    @SuppressWarnings("unused") @Inject Bar bar;
  }
  private static class ProviderFooBar {
    @SuppressWarnings("unused") @Inject Provider<Foo> foo;
    @SuppressWarnings("unused") @Inject Provider<Bar> bar;
  }
  private static class FooProvider implements Provider<Foo> {
    public Foo get() {
      return new FooImpl();
    }
  }

  @ImplementedBy(ImplByImpl.class)
  private static interface ImplBy {}
  private static class ImplByImpl implements ImplBy {}
  
  @ImplementedBy(ImplByScopedImpl.class)
  private static interface ImplByScoped {}
  @Singleton
  private static class ImplByScopedImpl implements ImplByScoped {}  

  @ProvidedBy(ProvByProvider.class)
  private static interface ProvBy {}
  private static class ProvByProvider implements Provider<ProvBy> {
    public ProvBy get() {
      return new ProvBy() {};
    }
  }
  
  private static class WantsTypeLiterals<T> {
    TypeLiteral<T> literal;
    Set<T> set;
    
    @Inject WantsTypeLiterals(TypeLiteral<T> literal, Set<T> set) {
      this.literal = literal;
      this.set = set;
      
    }
  }
}
