package com.airlock.iam.oauth2.infrastructure.factory.rest;

import com.airlock.iam.base.api.domain.model.exception.ServiceConfigurationException;
import com.airlock.iam.base.api.infrastructure.plugin.PluginConfigToLogic;
import com.airlock.iam.common.application.locale.LocalePreferenceConfiguration;
import com.airlock.iam.oauth2.api.domain.model.clientauthentication.ClientAuthenticationMethod;
import com.airlock.iam.oauth2.api.domain.service.clientauthentication.OAuth2ClientAuthentication;
import com.airlock.iam.oauth2.application.configuration.OAuth2AuthorizationServerConfigSpec;
import com.airlock.iam.oauth2.application.service.metadata.OAuth2MetadataService;
import com.airlock.iam.oauth2.domain.model.metadata.OAuth2AsCentricEndpointUriComposer;
import com.airlock.iam.oauth2.domain.model.metadata.OAuth2MetadataSettings;
import com.airlock.iam.oauth2.domain.model.metadata.UILocale;
import com.airlock.iam.oauth2.domain.service.reporting.OAuth2ReportingService;
import com.google.inject.Exposed;
import com.google.inject.PrivateModule;
import com.google.inject.Provides;
import com.google.inject.servlet.RequestScoped;
import java.util.List;
import java.util.stream.Collectors;

public final class OAuth2MetadataServiceModule extends PrivateModule {
   @Provides
   OAuth2MetadataSettings provideOAuth2MetadataSettings(
      OAuth2AuthorizationServerConfigSpec configSpec,
      OAuth2ReportingService reportingService,
      LocalePreferenceConfiguration localePreference,
      List<ClientAuthenticationMethod> supportedAuthenticationMethods
   ) {
      return ServiceConfigurationException.checkPresent(
         configSpec.getMetadataEndpointSettings(reportingService, this.uiLocales(localePreference), supportedAuthenticationMethods),
         "OAuth 2.0 Metadata endpoint not available."
      );
   }

   @Provides
   List<ClientAuthenticationMethod> provideClientAuthenticationMethods(PluginConfigToLogic pluginConfigToLogic, OAuth2AuthorizationServerConfigSpec configSpec) {
      return pluginConfigToLogic.<OAuth2ClientAuthentication>getLogic(configSpec.getTokenEndpointClientAuthentication()).supportedAuthenticationMethods();
   }

   private List<UILocale> uiLocales(LocalePreferenceConfiguration localePreference) {
      return localePreference.getValidLanguages().stream().map(UILocale::new).collect(Collectors.toList());
   }

   @Exposed
   @Provides
   @RequestScoped
   OAuth2MetadataService provideOAuth2MetadataService(OAuth2MetadataSettings metadataSettings, OAuth2AsCentricEndpointUriComposer uriComposer) {
      return new OAuth2MetadataService(metadataSettings, uriComposer);
   }

   protected void configure() {
   }
}
