package com.airlock.iam.admin.infrastructure.auth;

import com.airlock.iam.admin.api.infrastructure.AdminAuthenticationExtension;
import com.airlock.iam.admin.infrastructure.resource.auth.AdminappAuthenticationResource;
import com.airlock.iam.admin.infrastructure.resource.auth.AdminappSettingsResource;
import com.airlock.iam.common.api.application.configuration.RestApplicationConfiguration;
import com.airlock.iam.common.infrastructure.event.NoConfiguredEventSubscribersModule;
import com.airlock.iam.common.infrastructure.factory.Aes128GcmStateEncryptionModule;
import com.airlock.iam.common.infrastructure.factory.AirlockControlCookieServiceModule;
import com.airlock.iam.common.infrastructure.factory.CommonLoggingModule;
import com.airlock.iam.common.infrastructure.factory.CommonRestInfrastructureModule;
import com.airlock.iam.common.infrastructure.factory.ExpertModeRedisStateRepositoryModule;
import com.airlock.iam.common.infrastructure.factory.HttpRequestInformationModule;
import com.airlock.iam.common.infrastructure.factory.LocaleModule;
import com.airlock.iam.common.infrastructure.factory.MigratingStateEncryptionModule;
import com.airlock.iam.common.infrastructure.factory.PluginConfigToLogicModule;
import com.airlock.iam.common.infrastructure.factory.RedisStateRepositoryModule;
import com.airlock.iam.common.infrastructure.filter.general.CharsetResponseFilter;
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.google.inject.Module;
import java.util.Collection;
import java.util.List;
import java.util.stream.Stream;

@RestApplicationConfiguration(
   dependencyProviders = {
         "com.airlock.iam.admin.app.infrastructure.factory.auth",
         "com.airlock.iam.admin.app.infrastructure.factory.shared",
         "com.airlock.iam.admin.infrastructure.factory.auth",
         "com.airlock.iam.admin.infrastructure.factory.shared",
         "com.airlock.iam.base.infrastructure.factory"
   },
   beanMappers = {"com.airlock.iam.admin.infrastructure.mapper.auth", "com.airlock.iam.common.infrastructure.mapper"},
   exceptionMappers = "com.airlock.iam.common.infrastructure.exception"
)
public final class MainAdminAuthenticationExtension implements AdminAuthenticationExtension {
   public Collection<Class<? extends Module>> guiceModules() {
      return List.of(
         Aes128GcmStateEncryptionModule.class,
         AirlockControlCookieServiceModule.class,
         CommonLoggingModule.class,
         CommonRestInfrastructureModule.class,
         ExpertModeRedisStateRepositoryModule.class,
         HttpRequestInformationModule.class,
         LocaleModule.class,
         MigratingStateEncryptionModule.class,
         NoConfiguredEventSubscribersModule.class,
         PluginConfigToLogicModule.class,
         RedisStateRepositoryModule.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,
         LegacyInjectorInitFilter.class,
         LogContextFilter.class,
         MediaTypeNormalizationFilter.class,
         NoCacheFilter.class,
         SessionTerminationResponseFilter.class,
         SessionTimeoutResponseFilter.class,
         SystemAvailabilityFilter.class
      );
   }

   private static Stream<Class<?>> restResources() {
      return Stream.of(AdminappAuthenticationResource.class, AdminappSettingsResource.class);
   }
}
