package be.iminds.ilabt.jfed;

import be.iminds.ilabt.jfed.fedmon.webapi.service.json.Server;
import be.iminds.ilabt.jfed.log.Logger;
import be.iminds.ilabt.jfed.lowlevel.AnyCredential;
import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.TestCertHelper;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.AggregateManagerWrapper;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.impl.AutomaticAggregateManagerWrapper;
import be.iminds.ilabt.jfed.lowlevel.api_wrapper.impl.AutomaticUserAndSliceApiWrapper;
import be.iminds.ilabt.jfed.lowlevel.connection.JFedConnectionProvider;
import be.iminds.ilabt.jfed.util.GeniUrn;
import com.google.inject.Provides;

import javax.annotation.Nullable;
import javax.inject.Singleton;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.mockito.Mockito.mock;

/**
 * Fake automatic wrappers for testing
 *
 * This replaces the automatic wrappers by mocked objects.
 * This never goes low level, replies to requests are mocked at a high level.
 */
public class MockAutomaticWrappersTestCoreModule extends MockHttpRepliesTestCoreModule {
    public MockAutomaticWrappersTestCoreModule() {
        this(new TestCertHelper());
    }
    public MockAutomaticWrappersTestCoreModule(TestCertHelper testCertHelper) {
        super(testCertHelper);
    }

    @Override
    protected void configure() {
        bind(JFedConnectionProvider.class).to(TestSfaConnectionPool.class).in(Singleton.class);
//        bind(ConnectionFactory.class).to(BasicConnectionFactory.class).in(Singleton.class);
    }

    @Provides
    @Singleton
    public AutomaticAggregateManagerWrapper.AutomaticAggregateManagerWrapperFactory provideAutomaticAggregateManagerWrapperFactory() {
        return new AutomaticAggregateManagerWrapper.AutomaticAggregateManagerWrapperFactory() {
            Map<String, AutomaticAggregateManagerWrapper> mocks = new HashMap<String, AutomaticAggregateManagerWrapper>();

            @Override
            public AutomaticAggregateManagerWrapper create(Server amServer) throws AggregateManagerWrapper.NoAmException {
                return create(null, amServer);
            }

            @Override
            public AutomaticAggregateManagerWrapper create(Logger altLogger, Server amServer) throws AggregateManagerWrapper.NoAmException {
                assert amServer != null;
                String urn = amServer.getDefaultComponentManagerUrn();
                AutomaticAggregateManagerWrapper res = mocks.get(urn);
                if (res == null) {
                    res = mock(AutomaticAggregateManagerWrapper.class);
                    mocks.put(urn, res);
                }
                return res;
            }

            @Override
            public void setSpeaksFor(@Nullable List<AnyCredential> speaksForCredentials, @Nullable GeniUrn speakingForUrn) {
                throw new RuntimeException("no yet supported in testing");
            }

            @Override
            public boolean isSpeaksFor() {
                throw new RuntimeException("no yet supported in testing");
            }

            @Override
            public List<AnyCredential> getSpeaksForCredentials() {
                throw new RuntimeException("no yet supported in testing");
            }

            @Override
            public GeniUrn getSpeaksForUserUrn() {
                throw new RuntimeException("no yet supported in testing");
            }
        };
    }

    @Provides
    @Singleton
    public AutomaticUserAndSliceApiWrapper.AutomaticUserAndSliceApiWrapperFactory provideAutomaticUserAndSliceApiWrapperFactory() {
        return new AutomaticUserAndSliceApiWrapper.AutomaticUserAndSliceApiWrapperFactory() {
            AutomaticUserAndSliceApiWrapper res = mock(AutomaticUserAndSliceApiWrapper.class);
            @Override
            public AutomaticUserAndSliceApiWrapper create()  {
                return res;
            }

            @Override
            public AutomaticUserAndSliceApiWrapper create(Logger altLogger) {
                return res;
            }

            @Override
            public AutomaticUserAndSliceApiWrapper create(GeniUser altUser) {
                return res;
            }

            @Override
            public AutomaticUserAndSliceApiWrapper create(Logger altLogger, GeniUser altUser) {
                return res;
            }
        };
    }
}
