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

import com.airlock.iam.authentication.domain.model.rememberme.RememberMeLogoutAction;
import com.airlock.iam.common.application.service.logoutaction.LogoutActionService;
import com.airlock.iam.common.domain.model.logoutaction.LogoutAction;
import com.airlock.iam.login.domain.model.fingerprinting.ClientFingerprintingLogoutAction;
import com.airlock.iam.oauth2.application.configuration.OAuth2AsConfigsSpec;
import com.airlock.iam.oauth2.application.configuration.OAuth2AuthorizationServerConfigSpec;
import com.airlock.iam.oauth2.domain.model.logoutaction.BackchannelLogoutSettingsProvider;
import com.airlock.iam.oauth2.domain.model.logoutaction.OAuth2AsCentricTokenRemoveAction;
import com.airlock.iam.oauth2.domain.model.logoutaction.OidcBackchannelLogoutAction;
import com.airlock.iam.oauth2.domain.model.logoutaction.OidcBackchannelLogoutGenerator;
import com.airlock.iam.oauth2.domain.model.logoutaction.RemoveOpuasCookieLogoutAction;
import com.airlock.iam.oauth2.infrastructure.logoutaction.OidcBackchannelLogoutGeneratorImpl;
import com.airlock.iam.saml2.domain.service.logout.Saml2LogoutAction;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.multibindings.Multibinder;
import jakarta.inject.Provider;
import java.util.Optional;

public final class LogoutActionServiceModule extends PrivateModule {
   @Provides
   BackchannelLogoutSettingsProvider provideOpenIdProviders(Provider<Optional<OAuth2AsConfigsSpec>> authorizationServers) {
      return (opId, rpId) -> ((Optional)authorizationServers.get())
         .<OAuth2AuthorizationServerConfigSpec>flatMap(specs -> specs.findOAuth2AuthorizationServerConfigSpec(opId))
         .flatMap(spec -> spec.getBackchannelLogoutSettings(rpId));
   }

   protected void configure() {
      this.bind(OidcBackchannelLogoutGenerator.class).to(OidcBackchannelLogoutGeneratorImpl.class);
      Multibinder<LogoutAction> multibinder = Multibinder.newSetBinder(this.binder(), LogoutAction.class);
      addLogoutActions(multibinder);
      this.bind(LogoutActionService.class);
      this.expose(LogoutActionService.class);
   }

   private static void addLogoutActions(Multibinder<LogoutAction> multibinder) {
      multibinder.addBinding().to(OAuth2AsCentricTokenRemoveAction.class);
      multibinder.addBinding().to(RemoveOpuasCookieLogoutAction.class);
      multibinder.addBinding().to(RememberMeLogoutAction.class);
      multibinder.addBinding().to(Saml2LogoutAction.class);
      multibinder.addBinding().to(OidcBackchannelLogoutAction.class);
      multibinder.addBinding().to(ClientFingerprintingLogoutAction.class);
   }
}
