package com.commercetools.sunrise.common;

import com.commercetools.sunrise.cms.CmsService;
import com.commercetools.sunrise.common.basicauth.BasicAuth;
import com.commercetools.sunrise.common.contexts.UserContext;
import com.commercetools.sunrise.common.controllers.TestableSphereClient;
import com.commercetools.sunrise.common.pages.PageMeta;
import com.commercetools.sunrise.common.pages.PageMetaFactory;
import com.commercetools.sunrise.common.template.engine.TemplateEngine;
import com.commercetools.sunrise.common.template.i18n.I18nResolver;
import com.commercetools.sunrise.framework.MultiControllerComponentResolver;
import com.commercetools.sunrise.framework.SunriseComponent;
import com.commercetools.sunrise.hooks.RequestHookContext;
import com.commercetools.sunrise.hooks.actions.ActionHook;
import com.commercetools.sunrise.hooks.consumers.ConsumerHook;
import com.commercetools.sunrise.hooks.events.EventHook;
import com.commercetools.sunrise.hooks.requests.RequestHook;
import com.google.inject.AbstractModule;
import com.google.inject.util.Providers;
import com.neovisionaries.i18n.CountryCode;
import io.sphere.sdk.channels.Channel;
import io.sphere.sdk.client.SphereClient;
import io.sphere.sdk.customergroups.CustomerGroup;
import io.sphere.sdk.models.Reference;
import play.routing.RoutingDsl;

import javax.money.CurrencyUnit;
import javax.money.Monetary;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;

import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.concurrent.CompletableFuture.completedFuture;

public class DefaultTestModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(play.api.routing.Router.class).toInstance(new RoutingDsl().build().asScala()); // TODO Removes all routes to avoid having to resolve all injections while we have routes, remove later!
        bind(BasicAuth.class).toProvider(Providers.of(null));
        bind(SphereClient.class).toInstance(TestableSphereClient.ofEmptyResponse());
        bind(MultiControllerComponentResolver.class).toInstance(c -> emptyList());
        bind(PageMetaFactory.class).toInstance(PageMeta::new);
        bind(UserContext.class).toInstance(unsupportedUserContext());
        bind(I18nResolver.class).toInstance((l, i, h) -> Optional.empty());
        bind(TemplateEngine.class).toInstance((n, c) -> "");
        bind(CmsService.class).toInstance((l, c) -> completedFuture(Optional.empty()));
        bind(RequestHookContext.class).toInstance(unsupportedRequestHookContext());
    }

    private UserContext unsupportedUserContext() {
        return new UserContext() {
            @Override
            public CountryCode country() {
                return CountryCode.DE;
            }

            @Override
            public List<Locale> locales() {
                return singletonList(Locale.GERMANY);
            }

            @Override
            public CurrencyUnit currency() {
                return Monetary.getCurrency(Locale.GERMANY);
            }

            @Override
            public Optional<Reference<CustomerGroup>> customerGroup() {
                throw new UnsupportedOperationException();
            }

            @Override
            public Optional<Reference<Channel>> channel() {
                throw new UnsupportedOperationException();
            }
        };
    }

    private RequestHookContext unsupportedRequestHookContext() {
        return new RequestHookContext() {
            @Override
            public void add(final SunriseComponent component) {

            }

            @Override
            public <H extends EventHook> CompletionStage<?> runEventHook(final Class<H> hookClass, final Function<H, CompletionStage<?>> f) {
                return completedFuture(null);
            }

            @Override
            public <H extends ActionHook, R> CompletionStage<R> runActionHook(final Class<H> hookClass, final BiFunction<H, R, CompletionStage<R>> f, final R param) {
                return completedFuture(param);
            }

            @Override
            public <H extends RequestHook, R> R runUnaryOperatorHook(final Class<H> hookClass, final BiFunction<H, R, R> f, final R param) {
                return param;
            }

            @Override
            public <H extends ConsumerHook> void runConsumerHook(final Class<H> hookClass, final Consumer<H> consumer) {

            }

            @Override
            public CompletionStage<Object> allAsyncHooksCompletionStage() {
                return completedFuture(null);
            }
        };
    }
}

@@ -718,34 +718,20 @@
 e.hooks.
-RequestHookContext
+Hook
 ;%0Aimport
@@ -767,196 +767,8 @@
 oks.
-actions.ActionHook;%0Aimport com.commercetools.sunrise.hooks.consumers.ConsumerHook;%0Aimport com.commercetools.sunrise.hooks.events.EventHook;%0Aimport com.commercetools.sunrise.hooks.requests.
 Requ
@@ -770,24 +770,31 @@
 .RequestHook
+Context
 ;%0Aimport com
@@ -3640,21 +3640,16 @@
 extends 
-Event
 Hook%3E Co
@@ -3860,22 +3860,16 @@
 extends 
-Action
 Hook, R%3E
@@ -4105,23 +4105,16 @@
 extends 
-Request
 Hook, R%3E
@@ -4306,24 +4306,16 @@
 extends 
-Consumer
 Hook%3E vo

Fix test module