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

import com.airlock.iam.common.application.configuration.credential.BaseSsoTicketRequestAuthenticationConfig;
import com.airlock.iam.common.application.configuration.sso.DefaultSsoTicketContextDataExtractorConfig;
import com.airlock.iam.common.domain.model.sso.DefaultSsoTicketContextDataExtractorImpl;
import com.airlock.iam.common.domain.model.sso.SsoTicketContextDataExtractor;
import com.airlock.iam.common.domain.model.sso.SsoTicketExtractor;
import com.airlock.iam.common.domain.model.sso.SsoTicketKeyRoleExtractor;
import com.airlock.iam.common.domain.model.sso.SsoTicketRoleExtractor;
import com.airlock.iam.common.domain.model.sso.SsoTicketStepSettings;
import com.airlock.iam.common.domain.service.sso.AcceptedSsoTicketService;
import com.airlock.iam.common.domain.service.sso.SsoTicketService;
import com.airlock.iam.common.domain.service.sso.SsoTicketServiceImpl;
import java.util.List;
import java.util.Optional;

public final class SsoTicketServiceFactory {
   public static SsoTicketService createSsoTicketService(
      BaseSsoTicketRequestAuthenticationConfig config, Optional<AcceptedSsoTicketService> acceptedSsoTicketService, SsoTicketExtractor ticketExtractor
   ) {
      SsoTicketServiceImpl.SsoTicketServiceImplBuilder ssoTicketServiceBuilder = SsoTicketServiceImpl.builder()
         .ticketDecoder(config.getTicketDecoder())
         .ticketExtractors(List.of(ticketExtractor))
         .acceptedSsoTicketService(acceptedSsoTicketService)
         .roleExtractors(createRoleExtractors(config))
         .contextDataExtractors(createContextDataExtractors(config))
         .settings(new SsoTicketStepSettings(config.getUsernameKey(), config.getProvidedUsernameKey(), false, false, Optional.empty(), false));
      return ssoTicketServiceBuilder.build();
   }

   private static List<SsoTicketRoleExtractor> createRoleExtractors(BaseSsoTicketRequestAuthenticationConfig config) {
      return List.of(SsoTicketKeyRoleExtractor.fromTicketKeys(config.getRolesKey().stream().toList()));
   }

   private static List<SsoTicketContextDataExtractor> createContextDataExtractors(BaseSsoTicketRequestAuthenticationConfig config) {
      return config.getContextDataExtractors()
         .stream()
         .map(c -> new DefaultSsoTicketContextDataExtractorImpl(() -> (DefaultSsoTicketContextDataExtractorConfig)c))
         .map(SsoTicketContextDataExtractor.class::cast)
         .toList();
   }

   private SsoTicketServiceFactory() {
      throw new AssertionError();
   }
}
