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

import com.airlock.iam.factor.application.configuration.airlock2fa.Airlock2FASettings;
import com.airlock.iam.factor.application.configuration.airlock2fa.validation.Airlock2FAShortLivedQrCodeConfigValidator;
import com.airlock.iam.factor.domain.model.airlock2fa.Airlock2FAShortLivedOnlineQrCodeSettings;
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.api.application.configuration.message.Airlock2FAMessageProviderConfig;
import com.airlock.iam.flow.shared.application.configuration.airlock2fa.Airlock2FAApprovalStepConfig;
import com.airlock.iam.flow.shared.application.configuration.airlock2fa.DefaultAirlock2FAApprovalStepActions;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForPublicSelfServiceFlows;
import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
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 com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.IntegerProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Plugin(
   description = "<p>This step allows using Airlock 2FA to approve operations in public self-service flows.</p><p>Note that unlike identity verification steps, approval steps require an existing user and cannot prevent username enumeration (no stealth mode). It is therefore important that approval steps are only used <em>after</em> an identity verification step.</p>",
   displayName = "Airlock 2FA Public Self-Service Approval Step"
)
@PluginLicenseRestriction(moduleAffiliation = "Airlock2FA")
@Groups(
   openGroups = "Basic Settings",
   groupSequence = {"Basic Settings", "Short-Lived Online QR Code Settings", "Mobile Only Settings", "Tags/Guards", "Flow Control"}
)
@NextActions(DefaultAirlock2FAApprovalStepActions.Actions.class)
public final class Airlock2FAPublicSelfServiceApprovalStepConfig extends Airlock2FAApprovalStepConfig implements StepConfigForPublicSelfServiceFlows {
   public static final String AIRLOCK_2FA_PUBLIC_SELF_SERVICE_APPROVAL_STEP_DISPLAY_NAME = "Airlock 2FA Public Self-Service Approval Step";
   @PluginProperty(description = "Creates the message that will be displayed on the user's device.", optional = false)
   @GroupProperty(groupIdentifier = "Basic Settings")
   private Airlock2FAMessageProviderConfig messageProvider;
   @BooleanProperty(
      displayName = "Enable Push-to-All",
      description = "If Push-to-All for One-Touch is enabled, device selection is never required for One-Touch. Push notifications are sent to all devices of a user and approval can be given on any of the devices.<p>The combination of Push-to-All and \"Lock User on Fraud\" could have undesired effects, because users might report fraud in legitimate use-cases.</p>",
      defaultValue = "false",
      optional = true
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private boolean enablePushToAll;
   @BooleanProperty(
      displayName = "Enable Short-Lived Online QR Codes",
      description = "<p>Whether to enable short-lived Online QR Codes. Unlike regular Online QR Codes, these are refreshed regularly, allowing for shorter individual validities.</p>\n<p>Shorter validities enhance security, since forwarding a QR code to victims and tricking them to scan the QR code becomes more difficult if the available time window is small.</p><p>Note that this approval step should always be used after a verification step so that error response delays are not active. With response delays being active, QR codes are displayed delayed as well, which reduces their effective validity.</p>",
      defaultValue = "false",
      optional = true
   )
   @GroupProperty(groupIdentifier = "Short-Lived Online QR Code Settings")
   private boolean enableShortLivedOnlineQrCodes;
   @IntegerProperty(
      displayName = "QR Code Validity [s]",
      description = "<p>The maximum amount of time in seconds for which an Online QR Code is valid after it is first displayed to\nthe end user (ignoring latency). This duration includes the time defined for the validity overlap.\nIt only limits the time for scanning the QR code, not for the confirmation or approval afterwards.</p>\n<p><strong> Security Notice: The validity duration represents the attack window. Choosing a small validity makes\nattacks more difficult, in cases where an attacker attempts to forward a QR code to a victim for scanning.</strong></p>\n<p>This setting is only active if short-lived Online QR Codes are enabled.</p>",
      optional = true,
      defaultValue = 10,
      minValue = 3
   )
   @GroupProperty(groupIdentifier = "Short-Lived Online QR Code Settings")
   private int shortLivedQrCodeValidity;
   @IntegerProperty(
      displayName = "QR Code Validity Overlap [s]",
      description = "<p>Defines the duration in seconds during which the previously displayed QR Code is still valid after being\nreplaced by the next QR code in sequence.</p>\n<p>This provides time for pending requests to complete and ensures that a valid QR code is displayed at every\nmoment in time, provided that there are no network or performance issues.</p>\n<p>The validity overlap must meet the following criteria:</p>\n<ul>\n<li>It must be smaller than half the overall validity of the QR code.</li>\n<li>It must be larger than the Loginapp UI polling interval (1s) plus the network latency (IAM backend &rarr;\nLoginapp UI plus Mobile Device &rarr; Futurae Backend).<br/>\nNote that the polling interval may differ for custom user interfaces.</li>\n</ul>\n<p>This setting is only active if short-lived Online QR Codes are enabled.</p>",
      optional = true,
      defaultValue = 3,
      minValue = 2
   )
   @GroupProperty(groupIdentifier = "Short-Lived Online QR Code Settings")
   private int shortLivedQrCodeValidityOverlap;
   @IntegerProperty(
      displayName = "Session Timeout [s]",
      description = "<p>Maximum duration in seconds during which short-lived Online QR Codes are displayed until a session timeout occurs.</p>\n<p>This setting is used exclusively for short-lived Online QR Codes. It has no effect if short-lived Online QR Codes are disabled.</p>",
      optional = true,
      defaultValue = 60,
      minValue = 30,
      maxValue = 120,
      exampleValues = {30, 60, 90}
   )
   @GroupProperty(groupIdentifier = "Short-Lived Online QR Code Settings")
   private int shortLivedSessionTimeout;

   private Airlock2FAPublicSelfServiceApprovalStepConfig(
      FlowConditionConfig skipCondition,
      FlowConditionConfig preCondition,
      List<String> approvalFactors,
      boolean requiresActivation,
      List<TagConfig> tagsOnSuccess,
      @Nullable StepIdConfig stepId,
      List<InteractiveGotoTargetConfig> interactiveGotoTargets,
      List<DynamicStepActivationConfig> dynamicStepActivations,
      Map<String, StepIdConfig> onFailureGotos,
      List<ValueMapProviderConfig> customResponseAttributes,
      List<ValueMapProviderConfig> customFailureResponseAttributes,
      Airlock2FASettings airlock2faSettings,
      @Nullable String mobileOnlyRedirectUri,
      Airlock2FAMessageProviderConfig messageProvider,
      boolean enablePushToAll,
      boolean respectCooldownPeriod,
      boolean enableShortLivedOnlineQrCodes,
      int shortLivedQrCodeValidity,
      int shortLivedQrCodeValidityOverlap,
      int shortLivedSessionTimeout
   ) {
      super(
         skipCondition,
         preCondition,
         approvalFactors,
         requiresActivation,
         tagsOnSuccess,
         stepId,
         interactiveGotoTargets,
         dynamicStepActivations,
         onFailureGotos,
         customResponseAttributes,
         customFailureResponseAttributes,
         airlock2faSettings,
         mobileOnlyRedirectUri,
         respectCooldownPeriod
      );
      this.messageProvider = messageProvider;
      this.enablePushToAll = enablePushToAll;
      this.enableShortLivedOnlineQrCodes = enableShortLivedOnlineQrCodes;
      this.shortLivedQrCodeValidity = shortLivedQrCodeValidity;
      this.shortLivedQrCodeValidityOverlap = shortLivedQrCodeValidityOverlap;
      this.shortLivedSessionTimeout = shortLivedSessionTimeout;
   }

   @ConfigurationValidator(localOnly = true)
   public static void validateShortLivedQrCodeSettings(PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext ctx, Environment vEnv) throws ConfigurationException {
      Airlock2FAShortLivedQrCodeConfigValidator.runShortLivedSettingsValidation("shortLivedSessionTimeout", Optional.of("approvalFactors"), config, env, ctx);
   }

   public Airlock2FAMessageProviderConfig getMessageProvider() {
      return this.messageProvider;
   }

   public boolean isEnablePushToAll() {
      return this.enablePushToAll;
   }

   public Optional<Airlock2FAShortLivedOnlineQrCodeSettings> getShortLivedOnlineQrCodeSettings() {
      return this.enableShortLivedOnlineQrCodes
         ? Optional.of(
            Airlock2FAShortLivedOnlineQrCodeSettings.shortLivedOnlineQrCodeSettings(
               this.shortLivedQrCodeValidity, this.shortLivedQrCodeValidityOverlap, this.shortLivedSessionTimeout
            )
         )
         : Optional.empty();
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class Airlock2FAPublicSelfServiceApprovalStepConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private FlowConditionConfig skipCondition;
      @SuppressFBWarnings(justification = "generated code")
      private FlowConditionConfig preCondition;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<String> approvalFactors;
      @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 ArrayList<InteractiveGotoTargetConfig> interactiveGotoTargets;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<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 Airlock2FASettings airlock2faSettings;
      @SuppressFBWarnings(justification = "generated code")
      private String mobileOnlyRedirectUri;
      @SuppressFBWarnings(justification = "generated code")
      private Airlock2FAMessageProviderConfig messageProvider;
      @SuppressFBWarnings(justification = "generated code")
      private boolean enablePushToAll;
      @SuppressFBWarnings(justification = "generated code")
      private boolean respectCooldownPeriod;
      @SuppressFBWarnings(justification = "generated code")
      private boolean enableShortLivedOnlineQrCodes;
      @SuppressFBWarnings(justification = "generated code")
      private int shortLivedQrCodeValidity;
      @SuppressFBWarnings(justification = "generated code")
      private int shortLivedQrCodeValidityOverlap;
      @SuppressFBWarnings(justification = "generated code")
      private int shortLivedSessionTimeout;

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder approvalFactor(String approvalFactor) {
         if (this.approvalFactors == null) {
            this.approvalFactors = new ArrayList<>();
         }

         this.approvalFactors.add(approvalFactor);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder approvalFactors(
         Collection<? extends String> approvalFactors
      ) {
         if (approvalFactors == null) {
            throw new NullPointerException("approvalFactors cannot be null");
         }

         if (this.approvalFactors == null) {
            this.approvalFactors = new ArrayList<>();
         }

         this.approvalFactors.addAll(approvalFactors);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder clearApprovalFactors() {
         if (this.approvalFactors != null) {
            this.approvalFactors.clear();
         }

         return this;
      }

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder interactiveGotoTarget(
         InteractiveGotoTargetConfig interactiveGotoTarget
      ) {
         if (this.interactiveGotoTargets == null) {
            this.interactiveGotoTargets = new ArrayList<>();
         }

         this.interactiveGotoTargets.add(interactiveGotoTarget);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder interactiveGotoTargets(
         Collection<? extends InteractiveGotoTargetConfig> interactiveGotoTargets
      ) {
         if (interactiveGotoTargets == null) {
            throw new NullPointerException("interactiveGotoTargets cannot be null");
         }

         if (this.interactiveGotoTargets == null) {
            this.interactiveGotoTargets = new ArrayList<>();
         }

         this.interactiveGotoTargets.addAll(interactiveGotoTargets);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder clearInteractiveGotoTargets() {
         if (this.interactiveGotoTargets != null) {
            this.interactiveGotoTargets.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder dynamicStepActivation(
         DynamicStepActivationConfig dynamicStepActivation
      ) {
         if (this.dynamicStepActivations == null) {
            this.dynamicStepActivations = new ArrayList<>();
         }

         this.dynamicStepActivations.add(dynamicStepActivation);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder dynamicStepActivations(
         Collection<? extends DynamicStepActivationConfig> dynamicStepActivations
      ) {
         if (dynamicStepActivations == null) {
            throw new NullPointerException("dynamicStepActivations cannot be null");
         }

         if (this.dynamicStepActivations == null) {
            this.dynamicStepActivations = new ArrayList<>();
         }

         this.dynamicStepActivations.addAll(dynamicStepActivations);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder clearDynamicStepActivations() {
         if (this.dynamicStepActivations != null) {
            this.dynamicStepActivations.clear();
         }

         return this;
      }

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder airlock2faSettings(
         Airlock2FASettings airlock2faSettings
      ) {
         this.airlock2faSettings = airlock2faSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder mobileOnlyRedirectUri(
         @Nullable String mobileOnlyRedirectUri
      ) {
         this.mobileOnlyRedirectUri = mobileOnlyRedirectUri;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder messageProvider(
         Airlock2FAMessageProviderConfig messageProvider
      ) {
         this.messageProvider = messageProvider;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder enablePushToAll(boolean enablePushToAll) {
         this.enablePushToAll = enablePushToAll;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder respectCooldownPeriod(
         boolean respectCooldownPeriod
      ) {
         this.respectCooldownPeriod = respectCooldownPeriod;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder enableShortLivedOnlineQrCodes(
         boolean enableShortLivedOnlineQrCodes
      ) {
         this.enableShortLivedOnlineQrCodes = enableShortLivedOnlineQrCodes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder shortLivedQrCodeValidity(
         int shortLivedQrCodeValidity
      ) {
         this.shortLivedQrCodeValidity = shortLivedQrCodeValidity;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder shortLivedQrCodeValidityOverlap(
         int shortLivedQrCodeValidityOverlap
      ) {
         this.shortLivedQrCodeValidityOverlap = shortLivedQrCodeValidityOverlap;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder shortLivedSessionTimeout(
         int shortLivedSessionTimeout
      ) {
         this.shortLivedSessionTimeout = shortLivedSessionTimeout;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAPublicSelfServiceApprovalStepConfig build() {
         List approvalFactors = switch (this.approvalFactors == null ? 0 : this.approvalFactors.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.approvalFactors.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.approvalFactors));
         };

         List interactiveGotoTargets = switch (this.interactiveGotoTargets == null ? 0 : this.interactiveGotoTargets.size()) {
            case 0 -> Collections.emptyList();
            case 1 -> Collections.singletonList(this.interactiveGotoTargets.get(0));
            default -> Collections.unmodifiableList(new ArrayList<>(this.interactiveGotoTargets));
         };

         return new Airlock2FAPublicSelfServiceApprovalStepConfig(
            this.skipCondition,
            this.preCondition,
            approvalFactors,
            this.requiresActivation,
            this.tagsOnSuccess,
            this.stepId,
            interactiveGotoTargets,
            switch (this.dynamicStepActivations == null ? 0 : this.dynamicStepActivations.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.dynamicStepActivations.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.dynamicStepActivations));
            },
            this.onFailureGotos,
            this.customResponseAttributes,
            this.customFailureResponseAttributes,
            this.airlock2faSettings,
            this.mobileOnlyRedirectUri,
            this.messageProvider,
            this.enablePushToAll,
            this.respectCooldownPeriod,
            this.enableShortLivedOnlineQrCodes,
            this.shortLivedQrCodeValidity,
            this.shortLivedQrCodeValidityOverlap,
            this.shortLivedSessionTimeout
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "Airlock2FAPublicSelfServiceApprovalStepConfig.Airlock2FAPublicSelfServiceApprovalStepConfigBuilder(skipCondition="
            + this.skipCondition
            + ", preCondition="
            + this.preCondition
            + ", approvalFactors="
            + this.approvalFactors
            + ", requiresActivation="
            + this.requiresActivation
            + ", tagsOnSuccess="
            + this.tagsOnSuccess
            + ", stepId="
            + this.stepId
            + ", interactiveGotoTargets="
            + this.interactiveGotoTargets
            + ", dynamicStepActivations="
            + this.dynamicStepActivations
            + ", onFailureGotos="
            + this.onFailureGotos
            + ", customResponseAttributes="
            + this.customResponseAttributes
            + ", customFailureResponseAttributes="
            + this.customFailureResponseAttributes
            + ", airlock2faSettings="
            + this.airlock2faSettings
            + ", mobileOnlyRedirectUri="
            + this.mobileOnlyRedirectUri
            + ", messageProvider="
            + this.messageProvider
            + ", enablePushToAll="
            + this.enablePushToAll
            + ", respectCooldownPeriod="
            + this.respectCooldownPeriod
            + ", enableShortLivedOnlineQrCodes="
            + this.enableShortLivedOnlineQrCodes
            + ", shortLivedQrCodeValidity="
            + this.shortLivedQrCodeValidity
            + ", shortLivedQrCodeValidityOverlap="
            + this.shortLivedQrCodeValidityOverlap
            + ", shortLivedSessionTimeout="
            + this.shortLivedSessionTimeout
            + ")";
      }
   }
}
