package com.airlock.iam.publicselfservice.infrastructure;

import com.airlock.iam.common.api.application.configuration.RestApplicationConfiguration;
import com.airlock.iam.common.infrastructure.filter.general.CharsetResponseFilter;
import com.airlock.iam.common.infrastructure.filter.general.CombinedRequestDelayAndIamSessionFilter;
import com.airlock.iam.common.infrastructure.filter.general.ConfigurationLicensedFilter;
import com.airlock.iam.common.infrastructure.filter.general.ConfigurationPresentFilter;
import com.airlock.iam.common.infrastructure.filter.general.EnterExitFilter;
import com.airlock.iam.common.infrastructure.filter.general.LegacyInjectorInitFilter;
import com.airlock.iam.common.infrastructure.filter.general.LogContextFilter;
import com.airlock.iam.common.infrastructure.filter.general.MediaTypeNormalizationFilter;
import com.airlock.iam.common.infrastructure.filter.general.NoCacheFilter;
import com.airlock.iam.common.infrastructure.filter.general.SessionTerminationResponseFilter;
import com.airlock.iam.common.infrastructure.filter.general.SessionTimeoutResponseFilter;
import com.airlock.iam.common.infrastructure.filter.general.SystemAvailabilityFilter;
import com.airlock.iam.common.infrastructure.filter.security.CorsFilter;
import com.airlock.iam.common.infrastructure.filter.security.CsrfProtectionFilter;
import com.airlock.iam.common.infrastructure.reporting.factory.RequestEnvironmentReportingDataModule;
import com.airlock.iam.flow.shared.infrastructure.factory.step.Airlock2FADeleteDevicesStepModule;
import com.airlock.iam.flow.shared.infrastructure.factory.valueprovider.Airlock2FACooldownPredicateModule;
import com.airlock.iam.flow.shared.infrastructure.filter.general.FlowSessionCleanupResponseFilter;
import com.airlock.iam.flow.shared.infrastructure.filter.general.TagRemovalFilter;
import com.airlock.iam.flow.shared.infrastructure.filter.general.UserPrincipalSaveFilter;
import com.airlock.iam.flow.shared.infrastructure.filter.general.UserSessionCleanupResponseFilter;
import com.airlock.iam.keymanagementservice.infrastructure.factory.AwsKmsModule;
import com.airlock.iam.keymanagementservice.infrastructure.factory.AwsKmsPasswordDecryptionModule;
import com.airlock.iam.oauth2.infrastructure.factory.OAuth2ClientIdPatternUiTenantIdRuleModule;
import com.airlock.iam.oauth2.infrastructure.factory.valueprovider.OAuth2AccessTokenValueProviderModule;
import com.airlock.iam.publicselfservice.api.infrastructure.PublicSelfServiceExtension;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServicMatrixApprovalResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceAcknowledgeMessageFlowResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceAirlock2FAApprovalResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceCrontoApprovalResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceDeviceTokenFlowResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceDynamicStepActivationResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceEmailOtpResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceFidoApprovalResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceFlowResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceInteractiveGotoResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceInteractiveSelectionResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceMtanApprovalResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceMtanOtpResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceOathOtpApprovalResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceSecretQuestionsResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceSetPasswordResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceSsiResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceUiConfigurationResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceUserIdentificationResource;
import com.airlock.iam.publicselfservice.infrastructure.resource.PublicSelfServiceVascoOtpApprovalResource;
import com.airlock.iam.saml2.infrastructure.factory.idp.Saml2SpEntityIdPatternUiTenantIdRuleModule;
import com.airlock.iam.ssi.infrastructure.factory.ProcivisCoreSsiServiceModule;
import com.airlock.iam.ssi.infrastructure.factory.ProcivisDeskSsiServiceModule;
import com.airlock.iam.ssi.infrastructure.factory.SsiVerificationStepModule;
import com.google.inject.Module;
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;

@RestApplicationConfiguration(
   dependencyProviders = {
         "com.airlock.iam.base.infrastructure.factory",
         "com.airlock.iam.common.infrastructure.factory",
         "com.airlock.iam.fido.login.infrastructure.factory",
         "com.airlock.iam.flow.shared.infrastructure.factory",
         "com.airlock.iam.flow.ui.infrastructure.factory",
         "com.airlock.iam.login.app.infrastructure.factory.pub",
         "com.airlock.iam.login.app.infrastructure.factory.shared",
         "com.airlock.iam.login.rest.infrastructure.factory.event",
         "com.airlock.iam.login.rest.infrastructure.factory.shared",
         "com.airlock.iam.oauth2.infrastructure.factory.flow",
         "com.airlock.iam.publicselfservice.infrastructure.factory"
   },
   domainEventSubscribers = "com.airlock.iam.login.application.service.event.subscriber",
   exceptionMappers = {"com.airlock.iam.common.infrastructure.exception", "com.airlock.iam.flow.shared.infrastructure.exception"},
   beanMappers = {
         "com.airlock.iam.common.infrastructure.mapper",
         "com.airlock.iam.flow.shared.infrastructure.mapper",
         "com.airlock.iam.flow.ui.infrastructure.mapper",
         "com.airlock.iam.publicselfservice.infrastructure.mapper"
   }
)
public final class MainPublicSelfServiceExtension implements PublicSelfServiceExtension {
   @Override
   public Collection<Class<? extends Module>> guiceModules() {
      return List.of(
         Airlock2FACooldownPredicateModule.class,
         Airlock2FADeleteDevicesStepModule.class,
         AwsKmsModule.class,
         AwsKmsPasswordDecryptionModule.class,
         OAuth2AccessTokenValueProviderModule.class,
         OAuth2ClientIdPatternUiTenantIdRuleModule.class,
         ProcivisCoreSsiServiceModule.class,
         ProcivisDeskSsiServiceModule.class,
         RequestEnvironmentReportingDataModule.class,
         Saml2SpEntityIdPatternUiTenantIdRuleModule.class,
         SsiVerificationStepModule.class
      );
   }

   @Override
   public Collection<Class<?>> jaxRsComponents() {
      return Stream.concat(restFilters(), restResources()).toList();
   }

   private static Stream<Class<?>> restFilters() {
      return Stream.of(
         CharsetResponseFilter.class,
         ConfigurationLicensedFilter.class,
         ConfigurationPresentFilter.class,
         CorsFilter.class,
         CsrfProtectionFilter.class,
         EnterExitFilter.class,
         FlowSessionCleanupResponseFilter.class,
         CombinedRequestDelayAndIamSessionFilter.class,
         LegacyInjectorInitFilter.class,
         LogContextFilter.class,
         MediaTypeNormalizationFilter.class,
         NoCacheFilter.class,
         SessionTerminationResponseFilter.class,
         SessionTimeoutResponseFilter.class,
         SystemAvailabilityFilter.class,
         TagRemovalFilter.class,
         UserPrincipalSaveFilter.class,
         UserSessionCleanupResponseFilter.class
      );
   }

   private static Stream<Class<?>> restResources() {
      return Stream.of(
         PublicSelfServicMatrixApprovalResource.class,
         PublicSelfServiceAcknowledgeMessageFlowResource.class,
         PublicSelfServiceAirlock2FAApprovalResource.class,
         PublicSelfServiceCrontoApprovalResource.class,
         PublicSelfServiceDeviceTokenFlowResource.class,
         PublicSelfServiceDynamicStepActivationResource.class,
         PublicSelfServiceEmailOtpResource.class,
         PublicSelfServiceFidoApprovalResource.class,
         PublicSelfServiceFlowResource.class,
         PublicSelfServiceInteractiveGotoResource.class,
         PublicSelfServiceInteractiveSelectionResource.class,
         PublicSelfServiceMtanApprovalResource.class,
         PublicSelfServiceMtanOtpResource.class,
         PublicSelfServiceSecretQuestionsResource.class,
         PublicSelfServiceSetPasswordResource.class,
         PublicSelfServiceSsiResource.class,
         PublicSelfServiceUiConfigurationResource.class,
         PublicSelfServiceUserIdentificationResource.class,
         PublicSelfServiceVascoOtpApprovalResource.class,
         PublicSelfServiceOathOtpApprovalResource.class
      );
   }
}
