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

import com.airlock.iam.authentication.application.configuration.targetapp.OneShotResponseHeaderConfig;
import com.airlock.iam.authentication.application.configuration.targetapp.OneShotResponseMapperConfig;
import com.airlock.iam.authentication.application.configuration.targetapp.OneShotTargetApplicationConfig;
import com.airlock.iam.authentication.application.configuration.targetapp.TargetApplicationConfigSpec;
import com.airlock.iam.authentication.infrastructure.service.oneshot.OneShotResponseHeader;
import com.airlock.iam.authentication.infrastructure.service.oneshot.OneShotResponseMapper;
import com.airlock.iam.authentication.infrastructure.service.oneshot.OneShotResponseService;
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.service.session.AirlockControlCookieService;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import java.util.Collections;
import java.util.regex.Pattern;

public final class OneShotResponseServiceFactory {
   private static final Pattern MATCH_ALL = Pattern.compile(".*");
   private final Provider<PluginConfigToLogic> toLogic;
   private final Provider<AirlockControlCookieService> controlCookieService;

   @Inject
   public OneShotResponseServiceFactory(Provider<PluginConfigToLogic> toLogic, Provider<AirlockControlCookieService> controlCookieService) {
      this.toLogic = toLogic;
      this.controlCookieService = controlCookieService;
   }

   public OneShotResponseService createService(TargetApplicationConfigSpec config) {
      if (config instanceof OneShotTargetApplicationConfig oneShotConfig) {
         return new OneShotResponseService(
            oneShotConfig.getResponseMappers().stream().map(this::toMapper).toList(),
            new OneShotResponseMapper(
               MATCH_ALL,
               MATCH_ALL,
               401,
               Collections.emptyList(),
               AirlockControlCookieService.OneShotWorkflowAction.FINAL_RESPONSE,
               (AirlockControlCookieService)this.controlCookieService.get()
            ),
            new OneShotResponseMapper(
               MATCH_ALL,
               MATCH_ALL,
               403,
               Collections.emptyList(),
               AirlockControlCookieService.OneShotWorkflowAction.CONTINUE,
               (AirlockControlCookieService)this.controlCookieService.get()
            )
         );
      } else {
         throw new ServiceConfigurationException("Cannot create OneShotResponseService for target application of type " + config.getClass().getSimpleName());
      }
   }

   private OneShotResponseMapper toMapper(OneShotResponseMapperConfig config) {
      return new OneShotResponseMapper(
         config.getErrorCodeMatcher(),
         config.getNextStepMatcher(),
         config.getHttpStatusCode(),
         config.getHeaders().stream().map(this::toHeader).toList(),
         config.getWorkflow(),
         (AirlockControlCookieService)this.controlCookieService.get()
      );
   }

   private OneShotResponseHeader toHeader(OneShotResponseHeaderConfig config) {
      return new OneShotResponseHeader(config.getName(), ((PluginConfigToLogic)this.toLogic.get()).getLogic(config.getValue()));
   }
}
