package com.airlock.iam.authentication.application.configuration.sso;

import com.airlock.iam.common.application.configuration.credential.SsoTicketExtractorConfig;
import com.airlock.iam.common.application.configuration.sso.SsoTicketContextDataExtractorConfig;
import com.airlock.iam.common.application.configuration.sso.SsoTicketRoleExtractorConfig;
import com.airlock.iam.core.application.configuration.AcceptedSsoTicketRepositoryConfig;
import com.airlock.iam.core.misc.util.ticket.TicketDecoder;
import com.airlock.iam.flow.api.application.configuration.selection.FlowConditionConfig;
import com.airlock.iam.flow.api.application.configuration.step.AbstractFlowStepConfig;
import com.airlock.iam.flow.api.application.configuration.step.NonInteractiveStepConfig;
import com.airlock.iam.flow.api.application.configuration.step.StepIdConfig;
import com.airlock.iam.flow.api.application.configuration.tag.TagConfig;
import com.airlock.iam.flow.api.application.configuration.valueprovider.ValueMapProviderConfig;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForAuthenticationFlows;
import com.airlock.iam.plugin.api.annotation.property.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginListProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Map;
import lombok.NonNull;

public class SsoTicketIdentifyingStepConfigBase extends AbstractFlowStepConfig implements StepConfigForAuthenticationFlows, NonInteractiveStepConfig {
   @PluginListProperty(
      description = "List of ticket extractors that can extract an SSO ticket from the request. The ticket of the first successful extractor is used.",
      optional = false,
      minElements = 1
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private List<SsoTicketExtractorConfig> ticketExtractors;
   @PluginProperty(description = "Decodes the SSO ticket.", optional = false)
   @GroupProperty(groupIdentifier = "Basic Settings")
   private TicketDecoder ticketDecoder;
   @PluginProperty(
      description = "<p>Configures the repository used to store accepted SSO tickets and reject previously accepted ones.</p>\n<p>The in-memory repository cannot be used if multiple instances of IAM are deployed in parallel (failover, horizontal scaling).\nFurthermore, the in-memory repository does not preserve previously accepted SSO tickets across IAM restarts.</p>",
      displayName = "Accepted SSO Tickets Repository",
      optional = false,
      globalPluginReference = "globalAcceptedSsoTicketSettings"
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private AcceptedSsoTicketRepositoryConfig acceptedSsoTicketRepository;
   @StringProperty(
      description = "The ticket key where the username is stored. The value stored under this key is used to identify the user.",
      defaultValue = "username",
      optional = true
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private String usernameTicketKey;
   @PluginListProperty(
      description = "List of ticket tag extractors that extract flow tags from the ticket that the user receives, when they complete this step successfully. The tags of all configured extractors are granted <em>in addition</em> to the tags configured under 'Tags On Success'.",
      optional = true,
      minElements = 1
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private List<SsoTicketTagExtractorConfig> ticketTagExtractors;
   @PluginListProperty(
      description = "List of ticket role extractors that extract roles from the ticket, if this step is completed successfully. These roles are stored in the user session and can be accessed with the SSO Ticket Roles Provider.",
      optional = true,
      minElements = 1
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private List<SsoTicketRoleExtractorConfig> ticketRoleExtractors;
   @PluginListProperty(
      description = "List of ticket context data extractors that extract context data from the ticket, if this step is completed successfully. These data are stored in the user session and can be accessed with the SSO Ticket Context Data Provider.",
      optional = true,
      minElements = 1
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private List<SsoTicketContextDataExtractorConfig> ticketContextDataExtractors;

   protected SsoTicketIdentifyingStepConfigBase(
      FlowConditionConfig skipCondition,
      FlowConditionConfig preCondition,
      boolean requiresActivation,
      List<TagConfig> tagsOnSuccess,
      @Nullable StepIdConfig stepId,
      Map<String, StepIdConfig> onFailureGotos,
      List<ValueMapProviderConfig> customResponseAttributes,
      List<ValueMapProviderConfig> customFailureResponseAttributes,
      List<SsoTicketExtractorConfig> ticketExtractors,
      TicketDecoder ticketDecoder,
      @NonNull AcceptedSsoTicketRepositoryConfig acceptedSsoTicketRepository,
      String usernameTicketKey,
      List<SsoTicketTagExtractorConfig> ticketTagExtractors,
      List<SsoTicketRoleExtractorConfig> ticketRoleExtractors,
      List<SsoTicketContextDataExtractorConfig> ticketContextDataExtractors
   ) {
      super(skipCondition, preCondition, requiresActivation, tagsOnSuccess, stepId, onFailureGotos, customResponseAttributes, customFailureResponseAttributes);
      if (acceptedSsoTicketRepository == null) {
         throw new NullPointerException("acceptedSsoTicketRepository is marked non-null but is null");
      }

      this.ticketExtractors = ticketExtractors;
      this.ticketDecoder = ticketDecoder;
      this.acceptedSsoTicketRepository = acceptedSsoTicketRepository;
      this.usernameTicketKey = usernameTicketKey;
      this.ticketTagExtractors = ticketTagExtractors;
      this.ticketRoleExtractors = ticketRoleExtractors;
      this.ticketContextDataExtractors = ticketContextDataExtractors;
   }

   public List<SsoTicketExtractorConfig> getTicketExtractors() {
      return this.ticketExtractors;
   }

   public TicketDecoder getTicketDecoder() {
      return this.ticketDecoder;
   }

   public AcceptedSsoTicketRepositoryConfig getAcceptedSsoTicketRepository() {
      return this.acceptedSsoTicketRepository;
   }

   public String getUsernameTicketKey() {
      return this.usernameTicketKey;
   }

   public List<SsoTicketTagExtractorConfig> getTicketTagExtractors() {
      return this.ticketTagExtractors;
   }

   public List<SsoTicketRoleExtractorConfig> getTicketRoleExtractors() {
      return this.ticketRoleExtractors;
   }

   public List<SsoTicketContextDataExtractorConfig> getTicketContextDataExtractors() {
      return this.ticketContextDataExtractors;
   }

   @SuppressFBWarnings(justification = "generated code")
   public SsoTicketIdentifyingStepConfigBase() {
   }
}
