package com.nhl.bootique;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.util.Collection;
import java.util.Collections;

import org.junit.Before;
import org.junit.Test;

import com.google.inject.Binder;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.nhl.bootique.annotation.Args;
import com.nhl.bootique.it.ItestModuleProvider;

public class BootiqueIT {

	private String[] args;

	@Before
	public void before() {
		args = new String[] { "a", "b", "c" };
	}

	@Test
	public void testAutoLoadedProviders() {
		Collection<BQModuleProvider> autoLoaded = Bootique.app(args).autoLoadedProviders();

		assertEquals(1, autoLoaded.size());
		autoLoaded.forEach(m -> assertTrue(m instanceof ItestModuleProvider));
	}

	@Test
	public void testCreateInjector() {
		Injector i = Bootique.app(args).createInjector();

		String[] args = i.getInstance(Key.get(String[].class, Args.class));
		assertSame(this.args, args);
	}

	@Test
	public void testCreateInjector_Overrides() {
		Injector i = Bootique.app(args).override(BQCoreModule.class).with(M0.class).createInjector();

		String[] args = i.getInstance(Key.get(String[].class, Args.class));
		assertSame(M0.ARGS, args);
	}

	@Test
	public void testCreateInjector_Overrides_Multi_Level() {
		Injector i = Bootique.app(args).override(BQCoreModule.class).with(M0.class).override(M0.class).with(M1.class)
				.createInjector();

		String[] args = i.getInstance(Key.get(String[].class, Args.class));
		assertSame(M1.ARGS, args);
	}

	@Test
	public void testCreateInjector_OverridesWithProvider() {
		BQModuleProvider provider = new BQModuleProvider() {
			
			@Override
			public Module module() {
				return new M0();
			}
			
			@Override
			public Collection<Class<? extends Module>> overrides() {
				return Collections.singleton(BQCoreModule.class);
			}
		};

		Injector i = Bootique.app(args).module(provider).createInjector();

		String[] args = i.getInstance(Key.get(String[].class, Args.class));
		assertSame(M0.ARGS, args);
	}

	static class M0 implements Module {

		static String[] ARGS = { "1", "2", "3" };

		@Override
		public void configure(Binder binder) {
			binder.bind(String[].class).annotatedWith(Args.class).toInstance(ARGS);
		}
	}

	static class M1 implements Module {

		static String[] ARGS = { "x", "y", "z" };

		@Override
		public void configure(Binder binder) {
			binder.bind(String[].class).annotatedWith(Args.class).toInstance(ARGS);
		}
	}
}

@@ -216,33 +216,8 @@
 s;%0A%0A
-import org.junit.Before;%0A
 impo
@@ -506,50 +506,8 @@
 g%5B%5D 
-args;%0A%0A%09@Before%0A%09public void before() %7B%0A%09%09
 args
@@ -540,19 +540,16 @@
 , %22c%22 %7D;
-%0A%09%7D
 %0A%0A%09@Test
@@ -1670,19 +1670,16 @@
 der() %7B%0A
-%09%09%09
 %0A%09%09%09@Ove
@@ -1738,19 +1738,16 @@
 );%0A%09%09%09%7D%0A
-%09%09%09
 %0A%09%09%09@Ove

test cleanup