package com.airlock.iam.publicselfservice.application.configuration.steps;

import com.airlock.iam.core.domain.model.cronto.CrontoCheckingSettings;
import com.airlock.iam.core.misc.cronto.CrontoHandler;
import com.airlock.iam.flow.api.application.configuration.dynamicactivation.DynamicStepActivationConfig;
import com.airlock.iam.flow.api.application.configuration.selection.FlowConditionConfig;
import com.airlock.iam.flow.api.application.configuration.step.InteractiveGotoTargetConfig;
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.shared.application.configuration.cronto.CommonCrontoCheckingStepConfig;
import com.airlock.iam.flow.shared.domain.model.cronto.CrontoCheckingStep;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForPublicSelfServiceFlows;
import com.airlock.iam.plugin.api.annotation.config.Groups;
import com.airlock.iam.plugin.api.annotation.config.NextActions;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.license.PluginLicenseRestriction;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Map;

@Plugin(
   description = "<p>Cronto approval stealth step for public self-service flows.</p><p>This step displays a random dummy Cronto cryptogram and classifies any response OTP as wrong. Thus, it can never be successfully completed. It is intended to be used to avoid information leaking about users. Externally it behaves like the real Cronto approval step for public self-service flows.</p><p>This step is needed if the Cronto approval is used instead of a user verification step. Because the real Cronto approval step cannot be used for nonexistent or otherwise invalid users, a selection must be configured, using the \"Public Self-Service Allowed Condition\" to ensure that only users that are allowed to do public self-services enter the real Cronto step, while the other users end up in the stealth step.</p><p>Note that push and online validation have to be disabled in the real Cronto step, otherwise information would be leaked because it could behave differently for existing users (e.g. show push device selection). The configured authentication method ID must be the same as that of the real Cronto step. Also make sure the configured Flow Processors and Flow Restrictions in the public self-service flow allow nonexistent users and do not provide user feedback.</p>",
   displayName = "Cronto Approval Stealth Step"
)
@PluginLicenseRestriction(moduleAffiliation = "Cronto")
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Tags/Guards", "Flow Control", "Advanced Settings"})
@NextActions(CrontoCheckingStep.CrontoAuthStepActions.class)
public class CrontoPublicSelfServiceApprovalStealthStepConfig extends CommonCrontoCheckingStepConfig implements StepConfigForPublicSelfServiceFlows {
   public CrontoCheckingSettings getSettings() {
      return CrontoCheckingSettings.builder()
         .authenticatePushDevicesOnly(false)
         .pushSelectionForSingleDevice(false)
         .showLoginIdOnPush(false)
         .maxResponseRetries(this.getMaxResponseRetries())
         .crontoHandler(this.getCrontoHandler())
         .challengeType(CrontoHandler.CrontoChallengeType.TRANSACTION_APPROVAL)
         .build();
   }

   protected CrontoPublicSelfServiceApprovalStealthStepConfig(
      FlowConditionConfig skipCondition,
      FlowConditionConfig preCondition,
      boolean requiresActivation,
      List<TagConfig> tagsOnSuccess,
      @Nullable StepIdConfig stepId,
      List<InteractiveGotoTargetConfig> interactiveGotoTargets,
      List<DynamicStepActivationConfig> dynamicStepActivations,
      Map<String, StepIdConfig> onFailureGotos,
      List<ValueMapProviderConfig> customResponseAttributes,
      List<ValueMapProviderConfig> customFailureResponseAttributes,
      CrontoHandler crontoHandler,
      int maxResponseRetries,
      String authenticationMethodId
   ) {
      super(
         skipCondition,
         preCondition,
         requiresActivation,
         tagsOnSuccess,
         stepId,
         interactiveGotoTargets,
         dynamicStepActivations,
         onFailureGotos,
         customResponseAttributes,
         customFailureResponseAttributes,
         crontoHandler,
         maxResponseRetries,
         authenticationMethodId
      );
   }

   @SuppressFBWarnings(justification = "generated code")
   public static CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder builder() {
      return new CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder();
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class CrontoPublicSelfServiceApprovalStealthStepConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private FlowConditionConfig skipCondition;
      @SuppressFBWarnings(justification = "generated code")
      private FlowConditionConfig preCondition;
      @SuppressFBWarnings(justification = "generated code")
      private boolean requiresActivation;
      @SuppressFBWarnings(justification = "generated code")
      private List<TagConfig> tagsOnSuccess;
      @SuppressFBWarnings(justification = "generated code")
      private StepIdConfig stepId;
      @SuppressFBWarnings(justification = "generated code")
      private List<InteractiveGotoTargetConfig> interactiveGotoTargets;
      @SuppressFBWarnings(justification = "generated code")
      private List<DynamicStepActivationConfig> dynamicStepActivations;
      @SuppressFBWarnings(justification = "generated code")
      private Map<String, StepIdConfig> onFailureGotos;
      @SuppressFBWarnings(justification = "generated code")
      private List<ValueMapProviderConfig> customResponseAttributes;
      @SuppressFBWarnings(justification = "generated code")
      private List<ValueMapProviderConfig> customFailureResponseAttributes;
      @SuppressFBWarnings(justification = "generated code")
      private CrontoHandler crontoHandler;
      @SuppressFBWarnings(justification = "generated code")
      private int maxResponseRetries;
      @SuppressFBWarnings(justification = "generated code")
      private String authenticationMethodId;

      @SuppressFBWarnings(justification = "generated code")
      CrontoPublicSelfServiceApprovalStealthStepConfigBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder skipCondition(
         FlowConditionConfig skipCondition
      ) {
         this.skipCondition = skipCondition;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder preCondition(
         FlowConditionConfig preCondition
      ) {
         this.preCondition = preCondition;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder requiresActivation(
         boolean requiresActivation
      ) {
         this.requiresActivation = requiresActivation;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder tagsOnSuccess(
         List<TagConfig> tagsOnSuccess
      ) {
         this.tagsOnSuccess = tagsOnSuccess;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder stepId(@Nullable StepIdConfig stepId) {
         this.stepId = stepId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder interactiveGotoTargets(
         List<InteractiveGotoTargetConfig> interactiveGotoTargets
      ) {
         this.interactiveGotoTargets = interactiveGotoTargets;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder dynamicStepActivations(
         List<DynamicStepActivationConfig> dynamicStepActivations
      ) {
         this.dynamicStepActivations = dynamicStepActivations;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder onFailureGotos(
         Map<String, StepIdConfig> onFailureGotos
      ) {
         this.onFailureGotos = onFailureGotos;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder customResponseAttributes(
         List<ValueMapProviderConfig> customResponseAttributes
      ) {
         this.customResponseAttributes = customResponseAttributes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder customFailureResponseAttributes(
         List<ValueMapProviderConfig> customFailureResponseAttributes
      ) {
         this.customFailureResponseAttributes = customFailureResponseAttributes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder crontoHandler(CrontoHandler crontoHandler) {
         this.crontoHandler = crontoHandler;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder maxResponseRetries(int maxResponseRetries) {
         this.maxResponseRetries = maxResponseRetries;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder authenticationMethodId(
         String authenticationMethodId
      ) {
         this.authenticationMethodId = authenticationMethodId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoPublicSelfServiceApprovalStealthStepConfig build() {
         return new CrontoPublicSelfServiceApprovalStealthStepConfig(
            this.skipCondition,
            this.preCondition,
            this.requiresActivation,
            this.tagsOnSuccess,
            this.stepId,
            this.interactiveGotoTargets,
            this.dynamicStepActivations,
            this.onFailureGotos,
            this.customResponseAttributes,
            this.customFailureResponseAttributes,
            this.crontoHandler,
            this.maxResponseRetries,
            this.authenticationMethodId
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "CrontoPublicSelfServiceApprovalStealthStepConfig.CrontoPublicSelfServiceApprovalStealthStepConfigBuilder(skipCondition="
            + this.skipCondition
            + ", preCondition="
            + this.preCondition
            + ", requiresActivation="
            + this.requiresActivation
            + ", tagsOnSuccess="
            + this.tagsOnSuccess
            + ", stepId="
            + this.stepId
            + ", interactiveGotoTargets="
            + this.interactiveGotoTargets
            + ", dynamicStepActivations="
            + this.dynamicStepActivations
            + ", onFailureGotos="
            + this.onFailureGotos
            + ", customResponseAttributes="
            + this.customResponseAttributes
            + ", customFailureResponseAttributes="
            + this.customFailureResponseAttributes
            + ", crontoHandler="
            + this.crontoHandler
            + ", maxResponseRetries="
            + this.maxResponseRetries
            + ", authenticationMethodId="
            + this.authenticationMethodId
            + ")";
      }
   }
}
