package com.github.mlk.guice;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Key;
import com.google.inject.ProvisionException;
import com.google.inject.name.Names;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.util.Objects;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class MagicalLegacyProviderTest {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void whenConstructorDoesNotExistThenThrowProvisionException() {
        thrown.expect(ProvisionException.class);
        thrown.expectMessage(containsString("Unable to find a constructor matching"));

        new MagicalLegacyProvider<>(LegacyService.class, Key.get(ExpectedException.class));
    }

    @Test
    public void whenTypesHaveBeenBoundThenCreateNewInstance() {
        LegacyService legacyService = Guice.createInjector(
                new AbstractModule() {
                    @Override
                    protected void configure() {
                        bind(String.class).annotatedWith(Names.named("host")).toInstance("GUICE-HOST");
                        bind(Integer.class).annotatedWith(Names.named("port")).toInstance(8080);

                        bind(LegacyService.class).toProvider(new MagicalLegacyProvider<>(LegacyService.class, Key.get(String.class, Names.named("host")), Key.get(Integer.class, Names.named("port"))));
                    }
                }).getInstance(LegacyService.class);
        assertThat(legacyService, is(new LegacyService("GUICE-HOST", 8080)));
    }

    @Test
    public void whenUsingPrimativeTypes() {
        LegacyService legacyService = Guice.createInjector(
                new AbstractModule() {
                    @Override
                    protected void configure() {
                        bind(int.class).annotatedWith(Names.named("port")).toInstance(8080);

                        bind(LegacyService.class).toProvider(new MagicalLegacyProvider<>(LegacyService.class, Key.get(int.class, Names.named("port"))));
                    }
                }).getInstance(LegacyService.class);
        assertThat(legacyService, is(new LegacyService("DEFAULT", 8080)));
    }

    static class LegacyService {
        private final String host;
        private final Integer port;

        public LegacyService(int port) {
            this.host = "DEFAULT";
            this.port = port;
        }

        public LegacyService(String host, Integer port) {
            this.host = host;
            this.port = port;
        }

        @Override
        public int hashCode() {
            return Objects.hash(host, port);
        }

        @Override
        public boolean equals(Object obj) {
            if(obj instanceof LegacyService) {
                LegacyService other = (LegacyService)obj;
                return Objects.equals(host, other.host) && Objects.equals(port, other.port);
            }
            return false;
        }

        @Override
        public String toString() {
            return "LegacyService [host:" + host + ", port: " + port + "]";
        }
    }


}


@@ -209,16 +209,57 @@
 .Names;%0A
+import com.google.inject.spi.Dependency;%0A
 import o
@@ -364,16 +364,38 @@
 Objects;
+%0Aimport java.util.Set;
 %0A%0Aimport
@@ -2426,24 +2426,451 @@
 )));%0A    %7D%0A%0A
+    @Test%0A    public void dependencies() %7B%0A        MagicalLegacyProvider%3CLegacyService%3E subject = new MagicalLegacyProvider%3C%3E(LegacyService.class, Key.get(int.class, Names.named(%22port%22)));%0A        Set%3CDependency%3C?%3E%3E dependencies =  subject.getDependencies();%0A        assertThat(dependencies.size(), is(1));%0A        assertThat(dependencies.iterator().next(), is(Dependency.get(Key.get(int.class, Names.named(%22port%22)))));%0A    %7D%0A%0A
     static c

Test for dependencies