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

import com.airlock.iam.base.api.infrastructure.plugin.ModuleForConfig;
import com.airlock.iam.core.misc.authen.SecretStringGenerator;
import com.airlock.iam.techclientreg.application.configuration.oauth2dcr.DefaultOAuth2ClientRegistrationConfig;
import com.airlock.iam.techclientreg.domain.model.registration.AuthorizationCodeGrantProcessor;
import com.airlock.iam.techclientreg.domain.model.registration.ClientCredentialsGrantProcessor;
import com.airlock.iam.techclientreg.domain.model.registration.GrantProcessor;
import com.airlock.iam.techclientreg.domain.model.registration.ImplicitGrantProcessor;
import com.airlock.iam.techclientreg.domain.model.registration.RefreshTokenGrantProcessor;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import jakarta.inject.Provider;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@ModuleForConfig(DefaultOAuth2ClientRegistrationConfig.class)
public class DefaultOAuth2ClientRegistrationLogicModule extends PrivateModule {
   @Provides
   @Exposed
   Optional<SecretStringGenerator> provideSecretStringGenerator(DefaultOAuth2ClientRegistrationConfig config) {
      return Optional.ofNullable(config.getClientSecretGenerator());
   }

   @Provides
   @Exposed
   List<GrantProcessor> provideGrantProcessors(
      DefaultOAuth2ClientRegistrationConfig config,
      Provider<AuthorizationCodeGrantProcessor> authCodeGrantProcessor,
      Provider<ImplicitGrantProcessor> implicitGrantProcessor,
      Provider<ClientCredentialsGrantProcessor> clientCredGrantProcessor,
      Provider<RefreshTokenGrantProcessor> refreshTokenGrantProcessor
   ) {
      List<GrantProcessor> processors = new ArrayList<>();
      if (config.isAuthorizationCodeGrant()) {
         processors.add((GrantProcessor)authCodeGrantProcessor.get());
      }

      if (config.isImplicitGrant()) {
         processors.add((GrantProcessor)implicitGrantProcessor.get());
      }

      if (config.isClientCredentialsGrant()) {
         processors.add((GrantProcessor)clientCredGrantProcessor.get());
      }

      if (config.isAccessTokenRefresh()) {
         processors.add((GrantProcessor)refreshTokenGrantProcessor.get());
      }

      return processors;
   }

   protected void configure() {
   }
}
