package com.airlock.iam.transactionapproval.infrastructure;

import com.airlock.iam.common.api.application.configuration.RestApplicationConfiguration;
import com.airlock.iam.common.infrastructure.event.NoConfiguredEventSubscribersModule;
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.transactionapproval.api.infrastructure.TransactionApprovalExtension;
import com.airlock.iam.transactionapproval.infrastructure.filter.TransactionApprovalAuthenticationFilter;
import com.airlock.iam.transactionapproval.infrastructure.resource.TransactionApprovalDynamicStepActivationResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.TransactionApprovalFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.TransactionApprovalInteractiveGotoResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.TransactionApprovalParameterFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.airlock2fa.Airlock2FATransactionApprovalFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.cronto.CrontoTransactionApprovalFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.emailotp.EmailOtpTransactionApprovalFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.fido.FidoTransactionApprovalFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.identification.UserIdentificationFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.matrix.MatrixTransactionApprovalFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.message.TransactionApprovalMessageAcknowledgeFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.mtan.MtanTransactionApprovalFlowResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.otp.GenericOtpTransactionApprovalResource;
import com.airlock.iam.transactionapproval.infrastructure.resource.selection.TransactionApprovalInteractiveSelectionResource;
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.flow.shared.infrastructure.factory",
         "com.airlock.iam.transactionapproval.app.infrastructure.factory",
         "com.airlock.iam.transactionapproval.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",
         "com.airlock.iam.transactionapproval.infrastructure.mapper"
   },
   beanMappers = {
         "com.airlock.iam.common.infrastructure.mapper",
         "com.airlock.iam.flow.shared.infrastructure.mapper",
         "com.airlock.iam.transactionapproval.infrastructure.mapper"
   }
)
public final class MainTransactionApprovalExtension implements TransactionApprovalExtension {
   public Collection<Class<? extends Module>> guiceModules() {
      return List.of(
         Airlock2FACooldownPredicateModule.class,
         Airlock2FADeleteDevicesStepModule.class,
         NoConfiguredEventSubscribersModule.class,
         RequestEnvironmentReportingDataModule.class
      );
   }

   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,
         TransactionApprovalAuthenticationFilter.class,
         UserPrincipalSaveFilter.class,
         UserSessionCleanupResponseFilter.class
      );
   }

   private static Stream<Class<?>> restResources() {
      return Stream.of(
         Airlock2FATransactionApprovalFlowResource.class,
         CrontoTransactionApprovalFlowResource.class,
         EmailOtpTransactionApprovalFlowResource.class,
         FidoTransactionApprovalFlowResource.class,
         GenericOtpTransactionApprovalResource.class,
         MatrixTransactionApprovalFlowResource.class,
         MtanTransactionApprovalFlowResource.class,
         TransactionApprovalDynamicStepActivationResource.class,
         TransactionApprovalFlowResource.class,
         TransactionApprovalInteractiveGotoResource.class,
         TransactionApprovalInteractiveSelectionResource.class,
         TransactionApprovalMessageAcknowledgeFlowResource.class,
         TransactionApprovalParameterFlowResource.class,
         UserIdentificationFlowResource.class
      );
   }
}
