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

import com.airlock.iam.admin.application.configuration.oauth2.OAuth2TokenController;
import com.airlock.iam.admin.domain.model.token.TokenController;
import com.airlock.iam.base.api.domain.model.exception.ServiceConfigurationException;
import com.airlock.iam.database.infrastructure.JooqConfig;
import com.airlock.iam.oauth2.application.configuration.consentstorage.OAuth2ConsentRepositoryConfig;
import com.airlock.iam.oauth2.application.service.DefaultOAuth2ConsentService;
import com.airlock.iam.oauth2.domain.model.consent.OAuth2ConsentRepository;
import com.airlock.iam.oauth2.domain.service.OAuth2ConsentService;
import com.airlock.iam.oauth2.infrastructure.repository.OAuth2ConsentRepositoryImpl;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import jakarta.inject.Provider;
import java.util.Optional;

public class OAuth2ConsentServiceModule extends PrivateModule {
   @Provides
   OAuth2TokenController provideTokenController(Provider<TokenController.TokenControllers> tokenControllers) {
      Optional<OAuth2TokenController> tokenController = ((TokenController.TokenControllers)tokenControllers.get()).ofId("OAUTH2");
      return (OAuth2TokenController)ServiceConfigurationException.checkPresent(tokenController, "OAuth 2.0 Token controller must be configured.");
   }

   @Provides
   Optional<OAuth2ConsentRepositoryConfig> provideConsentRepositoryConfig(OAuth2TokenController tokenController) {
      return tokenController.consentRepository();
   }

   @Provides
   Optional<JooqConfig> provideJooqConfig(Optional<OAuth2ConsentRepositoryConfig> consentRepositoryConfig) {
      return consentRepositoryConfig.map(OAuth2ConsentRepositoryConfig::jooqConfig);
   }

   @Provides
   Optional<OAuth2ConsentRepository> provideConsentRepository(Optional<JooqConfig> jooqConfig) {
      return jooqConfig.map(OAuth2ConsentRepositoryImpl::new);
   }

   protected void configure() {
      this.bind(OAuth2ConsentService.class).to(DefaultOAuth2ConsentService.class);
      this.expose(OAuth2ConsentService.class);
   }
}
