package com.airlock.iam.flow.shared.application.configuration.airlock2fa;

import com.airlock.iam.factor.application.configuration.airlock2fa.Airlock2FASettings;
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.AbstractInteractiveFlowStepConfig;
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.domain.model.airlock2fa.Airlock2FADeviceEditStep;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForAuthenticationFlows;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForSelfServiceFlows;
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.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Map;

@Plugin(
   description = "<p>Step to edit a newly added Airlock 2FA device.</p><p>This step can be used after an 'Airlock 2FA Activation Step' to, for example, change the display name of the new device. See the documentation of 'Airlock 2FA Activation Step' to know in which cases this step should be configured as an 'Authentication Flow Step' or as a 'Protected Self-Service Flow Step'.</p><p>Note that this step can <strong>not</strong> be used to edit already activated Airlock 2FA devices (which were not activated by an 'Airlock 2FA Activation Step' in the same session). For this use-case, a 'Protected Self-Service Flow' with an 'Airlock 2FA Device Edit Initiation Step' and a corresponding 'Apply Changes Step' should be used.</p>",
   displayName = "Airlock 2FA Device Edit Step"
)
@PluginLicenseRestriction(moduleAffiliation = "Airlock2FA")
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Tags/Guards", "Flow Control"})
@NextActions(Airlock2FADeviceEditStep.Airlock2FADeviceEditStepActions.class)
public class Airlock2FADeviceEditStepConfig
   extends AbstractInteractiveFlowStepConfig
   implements StepConfigForAuthenticationFlows,
   StepConfigForSelfServiceFlows {
   @PluginProperty(
      displayName = "Airlock 2FA Settings",
      description = "Settings of Airlock 2FA.",
      optional = false,
      globalPluginReference = "globalAirlock2FASettings"
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private Airlock2FASettings airlock2faSettings;
   @BooleanProperty(
      description = "If enabled, this step will ensure that the display name is not already used by another device.",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private boolean enforceUniqueDisplayNames;

   public Airlock2FADeviceEditStepConfig(
      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,
      boolean enforceUniqueDisplayNames
   ) {
      super(
         skipCondition,
         preCondition,
         requiresActivation,
         tagsOnSuccess,
         stepId,
         interactiveGotoTargets,
         dynamicStepActivations,
         onFailureGotos,
         customResponseAttributes,
         customFailureResponseAttributes
      );
      this.airlock2faSettings = airlock2faSettings;
      this.enforceUniqueDisplayNames = enforceUniqueDisplayNames;
   }

   public Airlock2FASettings getAirlock2faSettings() {
      return this.airlock2faSettings;
   }

   public boolean enforceUniqueDisplayNames() {
      return this.enforceUniqueDisplayNames;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class Airlock2FADeviceEditStepConfigBuilder {
      @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 boolean enforceUniqueDisplayNames;

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

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

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

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

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

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

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

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

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

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FADeviceEditStepConfig.Airlock2FADeviceEditStepConfigBuilder enforceUniqueDisplayNames(boolean enforceUniqueDisplayNames) {
         this.enforceUniqueDisplayNames = enforceUniqueDisplayNames;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "Airlock2FADeviceEditStepConfig.Airlock2FADeviceEditStepConfigBuilder(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
            + ", enforceUniqueDisplayNames="
            + this.enforceUniqueDisplayNames
            + ")";
      }
   }
}
