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

import com.airlock.iam.authentication.application.configuration.kerberos.KerberosAuthStepConfig;
import com.airlock.iam.authentication.domain.model.kerberos.KerberosAuthSettings;
import com.airlock.iam.authentication.domain.model.kerberos.KerberosAuthStepSession;
import com.airlock.iam.authentication.domain.model.kerberos.SpnegoTicketExtractor;
import com.airlock.iam.authentication.infrastructure.service.kerberos.SpnegoTicketExtractorImpl;
import com.airlock.iam.base.api.infrastructure.plugin.ModuleForConfig;
import com.airlock.iam.common.api.domain.model.authmethod.AuthenticationMethod;
import com.airlock.iam.core.misc.impl.authen.AuthenticationMethodFactory;
import com.airlock.iam.flow.api.domain.model.session.FlowSession;
import com.airlock.iam.flow.infrastructure.step.StepSessionModuleHelper;
import com.airlock.iam.login.application.service.kerberos.ConfigLoggingInfo;
import com.airlock.iam.login.application.service.kerberos.KerberosService;
import com.airlock.iam.login.application.service.kerberos.KerberosServiceImpl;
import com.airlock.iam.login.application.service.kerberos.KerberosValidateActionFactory;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import java.util.Optional;

@ModuleForConfig(KerberosAuthStepConfig.class)
public final class KerberosAuthStepModule extends PrivateModule {
   @Provides
   KerberosValidateActionFactory provideKerberosValidateActionFactory() {
      return new KerberosValidateActionFactory();
   }

   @Provides
   Optional<ConfigLoggingInfo> provideConfigLoggingInfo(KerberosAuthStepConfig config) {
      return Optional.of(new ConfigLoggingInfo(config.getServicePrincipal(), config.getKeytabFile()));
   }

   @Exposed
   @Provides
   KerberosAuthStepSession provideKerberosAuthStepSession(FlowSession flowSession) {
      return StepSessionModuleHelper.retrieveStepSession(flowSession, KerberosAuthStepSession.class);
   }

   @Exposed
   @Provides
   KerberosService provideKerberosService(
      KerberosAuthStepConfig config, KerberosValidateActionFactory kerberosValidateActionFactory, Optional<ConfigLoggingInfo> configLoggingInfo
   ) {
      return new KerberosServiceImpl(config.getServiceSubject(), kerberosValidateActionFactory, configLoggingInfo);
   }

   @Exposed
   @Provides
   KerberosAuthSettings provideKerberosAuthenticationSettings(KerberosAuthStepConfig config) {
      return new KerberosAuthSettings(config.getServicePrincipal(), config.isStripDomainFromUsername());
   }

   @Exposed
   @Provides
   AuthenticationMethod provideAuthenticationMethod(KerberosAuthStepConfig config) {
      return AuthenticationMethodFactory.authMethodFor(config.getAuthenticationMethodId());
   }

   protected void configure() {
      this.bind(SpnegoTicketExtractor.class).to(SpnegoTicketExtractorImpl.class);
      this.expose(SpnegoTicketExtractor.class);
   }
}
