package com.airlock.iam.admin.infrastructure.factory.prot;

import com.airlock.iam.admin.application.configuration.oathotp.OathOtpTokenController;
import com.airlock.iam.admin.application.service.token.oathotp.AdminOathOtpTokenServiceImpl;
import com.airlock.iam.admin.application.service.token.oathotp.AdminTotpTokenService;
import com.airlock.iam.admin.application.service.token.oathotp.AdminTotpTokenServiceImpl;
import com.airlock.iam.admin.application.service.token.oathotp.HotpTokenService;
import com.airlock.iam.admin.application.service.token.oathotp.HotpTokenServiceImpl;
import com.airlock.iam.admin.domain.model.authmethod.AuthenticationMethod;
import com.airlock.iam.admin.domain.model.token.TokenController;
import com.airlock.iam.admin.domain.model.token.oathotp.OathOtpAuthenticationMethod;
import com.airlock.iam.base.api.domain.model.exception.ServiceConfigurationException;
import com.airlock.iam.core.misc.impl.tokenverifier.oathotp.OathOtpSettings;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.servlet.RequestScoped;
import jakarta.inject.Named;
import java.util.Optional;

public class AdminOathOtpTokenServiceModule extends PrivateModule {
   @Provides
   OathOtpTokenController provideOathOtpTokenController(TokenController.TokenControllers tokenControllers) {
      Optional<OathOtpTokenController> optionalTokenController = this.tokenController(tokenControllers);
      return (OathOtpTokenController)ServiceConfigurationException.checkPresent(optionalTokenController, "OATH OTP token controller must be configured.");
   }

   @Provides
   OathOtpSettings provideOathOtpSettings(OathOtpTokenController tokenController) {
      return tokenController.getOathOtpSettings();
   }

   @Provides
   @RequestScoped
   @Named("OATH_OTP")
   @Exposed
   AuthenticationMethod provideAuthMethod(AdminOathOtpTokenServiceImpl service, OathOtpTokenController tokenController) {
      return OathOtpAuthenticationMethod.builder().tokenController(tokenController).service(service).build();
   }

   protected void configure() {
      this.bind(AdminTotpTokenService.class).to(AdminTotpTokenServiceImpl.class).in(RequestScoped.class);
      this.expose(AdminTotpTokenService.class);
      this.bind(HotpTokenService.class).to(HotpTokenServiceImpl.class).in(RequestScoped.class);
      this.expose(HotpTokenService.class);
   }

   private Optional<OathOtpTokenController> tokenController(TokenController.TokenControllers tokenControllers) {
      return tokenControllers.ofId("OATH_OTP");
   }
}
