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

import com.airlock.iam.authentication.domain.model.airlock2fa.Airlock2FAAuthenticationStep;
import com.airlock.iam.authentication.domain.model.airlock2fa.Airlock2FAMobileOnlyAuthenticationStep;
import com.airlock.iam.factor.application.configuration.airlock2fa.Airlock2FASettings;
import com.airlock.iam.factor.domain.model.airlock2fa.Airlock2FAMobileOnlyRedirectUri;
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.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.GroupProperty;
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 java.util.Optional;

@Plugin(
   description = "Airlock 2FA authentication step for \"Mobile Only\" authentication.<p>This step allows an app on an enrolled mobile device to authenticate with Airlock 2FA by using the Loginapp REST API. The authentication is either performed by switching from the main app to a dedicated authentication app (Airlock 2FA, Futurae or compatible) or directly within an app that has an integrated SDK.</p><p>There is no UI for this step.</p><p>The identifier of the authentication method for this step is 'AIRLOCK_2FA' and is also the identifier for failed authentication attempts.</p>",
   displayName = "Airlock 2FA Mobile Only Authentication Step"
)
@PluginLicenseRestriction(moduleAffiliation = "Airlock2FA")
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Tags/Guards", "Flow Control", "Advanced Settings"})
@NextActions(
   {
         Airlock2FAMobileOnlyAuthenticationStep.Airlock2FAMobileOnlyAuthenticationStepAction.class,
         Airlock2FAAuthenticationStep.Airlock2FAAuthenticationStepAction.class
   }
)
public final class Airlock2FAMobileOnlyAuthenticationStepConfig extends Airlock2FAAuthenticationStepConfig {
   static final String AIRLOCK_2FA_MOBILE_ONLY_AUTHENTICATION_STEP_DISPLAY_NAME = "Airlock 2FA Mobile Only Authentication Step";
   @StringProperty(
      description = "The URI used on iOS to switch from the authentication app (Airlock 2FA or compatible) back to the main app where the authentication was initiated. This value is not applicable if the authentication is directly performed by the main app. Furthermore, this value is ignored on Android, where the back stack mechanism is used instead.",
      displayName = "Redirect URI",
      optional = true
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private String redirectUri;
   @StringProperty(
      description = "Allows to override the scheme of the mobile authentication URI which is returned by the authentication step.\nThe scheme of the authentication URI determines, which app to open on the mobile device for authentication.\nThis is useful when migrating from one authentication app (such as Airlock 2FA) to a different authentication app.\nFor example, during a migration, this step can be used to support the previous authentication app by overriding\nthe scheme of the new app with the scheme of the previous app.\n",
      validationRegex = "^[a-zA-Z][a-zA-Z0-9\\+\\-\\.]*$",
      exampleValues = {"airlock2fa", "OneApp-1"},
      optional = true
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private String schemeOverride;

   private Airlock2FAMobileOnlyAuthenticationStepConfig(
      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,
      Airlock2FASettings airlock2faSettings,
      String redirectUri,
      boolean respectCooldownPeriod
   ) {
      super(
         skipCondition,
         preCondition,
         requiresActivation,
         tagsOnSuccess,
         stepId,
         interactiveGotoTargets,
         dynamicStepActivations,
         onFailureGotos,
         customResponseAttributes,
         customFailureResponseAttributes,
         airlock2faSettings,
         respectCooldownPeriod
      );
      this.redirectUri = redirectUri;
   }

   public Optional<Airlock2FAMobileOnlyRedirectUri> getRedirectUri() {
      return Optional.ofNullable(this.redirectUri).map(Airlock2FAMobileOnlyRedirectUri::new);
   }

   @Nullable
   public String getSchemeOverride() {
      return this.schemeOverride;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class Airlock2FAMobileOnlyAuthenticationStepConfigBuilder {
      @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 Airlock2FASettings airlock2faSettings;
      @SuppressFBWarnings(justification = "generated code")
      private String redirectUri;
      @SuppressFBWarnings(justification = "generated code")
      private boolean respectCooldownPeriod;

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

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

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

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

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

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

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

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

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

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAMobileOnlyAuthenticationStepConfig.Airlock2FAMobileOnlyAuthenticationStepConfigBuilder redirectUri(String redirectUri) {
         this.redirectUri = redirectUri;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FAMobileOnlyAuthenticationStepConfig build() {
         return new Airlock2FAMobileOnlyAuthenticationStepConfig(
            this.skipCondition,
            this.preCondition,
            this.requiresActivation,
            this.tagsOnSuccess,
            this.stepId,
            this.interactiveGotoTargets,
            this.dynamicStepActivations,
            this.onFailureGotos,
            this.customResponseAttributes,
            this.customFailureResponseAttributes,
            this.airlock2faSettings,
            this.redirectUri,
            this.respectCooldownPeriod
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "Airlock2FAMobileOnlyAuthenticationStepConfig.Airlock2FAMobileOnlyAuthenticationStepConfigBuilder(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
            + ", airlock2faSettings="
            + this.airlock2faSettings
            + ", redirectUri="
            + this.redirectUri
            + ", respectCooldownPeriod="
            + this.respectCooldownPeriod
            + ")";
      }
   }
}
