package com.airlock.iam.authentication.infrastructure.factory;

import com.airlock.iam.authentication.domain.model.rememberme.RememberMeCookie;
import com.airlock.iam.authentication.domain.model.rememberme.RememberMeRequest;
import com.airlock.iam.authentication.domain.model.rememberme.RememberMeResponse;
import com.airlock.iam.authentication.domain.service.rememberme.RememberMeLogoutService;
import com.airlock.iam.authentication.domain.service.rememberme.RememberMeLogoutServiceImpl;
import com.airlock.iam.authentication.infrastructure.rememberme.RememberMeRequestImpl;
import com.airlock.iam.authentication.infrastructure.rememberme.RememberMeResponseImpl;
import com.airlock.iam.common.application.configuration.rememberme.JspRememberMeConfig;
import com.airlock.iam.common.application.configuration.rememberme.RememberMeConfig;
import com.airlock.iam.common.domain.model.user.PrincipalInfo;
import com.airlock.iam.database.infrastructure.JooqConfig;
import com.airlock.iam.flow.shared.domain.model.rememberme.RememberMeTokenRepository;
import com.airlock.iam.flow.shared.infrastructure.rememberme.RememberMeTokenRepositoryImpl;
import com.airlock.iam.log.api.helpdesk.HelpdeskLogger;
import com.airlock.iam.log.api.signing.SigningLogger;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import jakarta.inject.Provider;
import java.util.Optional;

public class RememberMeLogoutServiceModule extends PrivateModule {
   @Provides
   RememberMeConfig.LogoutBehaviour provideLogoutBehaviour(Optional<RememberMeConfig> config) {
      return config.map(RememberMeConfig::getLogoutBehavior).orElse(RememberMeConfig.LogoutBehaviour.KEEP_COOKIE);
   }

   @Provides
   JooqConfig provideJooqConfig(RememberMeConfig config) {
      return config.getRepository().jooqConfig();
   }

   @Provides
   Optional<JspRememberMeConfig> provideJspRememberMeConfig() {
      return Optional.empty();
   }

   @Provides
   Optional<RememberMeCookie.RememberMeCookieBuilder> provideRememberMeJspCookieBuilder() {
      return Optional.empty();
   }

   @Provides
   @Exposed
   Optional<RememberMeLogoutService> provideLogoutActionService(
      RememberMeConfig.LogoutBehaviour logoutBehaviour,
      Optional<RememberMeConfig> config,
      Provider<RememberMeRequest> request,
      Provider<RememberMeResponse> response,
      Provider<RememberMeTokenRepository> repository,
      Provider<PrincipalInfo> principalInfo,
      HelpdeskLogger helpdeskLogger,
      SigningLogger signingLogger
   ) {
      return config.map(
         c -> RememberMeLogoutServiceImpl.builder()
            .logoutBehaviour(logoutBehaviour)
            .helpdeskLogger(helpdeskLogger)
            .signingLogger(signingLogger)
            .request(request)
            .response(response)
            .tokenRepository(repository)
            .principalInfo(principalInfo)
            .build()
      );
   }

   protected void configure() {
      this.bind(RememberMeRequest.class).to(RememberMeRequestImpl.class);
      this.bind(RememberMeResponse.class).to(RememberMeResponseImpl.class);
      this.bind(RememberMeTokenRepository.class).to(RememberMeTokenRepositoryImpl.class);
   }
}
