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

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.AbstractFlowStepConfig;
import com.airlock.iam.flow.api.application.configuration.step.InteractiveGotoTargetConfig;
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.shared.application.configuration.newdevice.NewDeviceCookieConfig;
import com.airlock.iam.flow.types.api.application.configuration.step.StepConfigForAuthenticationFlows;
import com.airlock.iam.plugin.api.annotation.config.Groups;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
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 = "Step which publishes an event if the user logged in from a new device:\n<ol>\n<li>Looks for a cookie with the configured name.</li>\n<li>Decrypts the cookie with the configured key.</li>\n<li>Uses the cookie to find out if the user already logged in from the current device.</li>\n<li>Triggers an event if it is the first login from that device or the time since the last login exceeds the configured validity.</li>\n<li>Updates the cookie and sets it in the response.</li>\n</ol>",
   displayName = "Login From New Device Step"
)
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Tags/Guards", "Flow Control", "Advanced Settings"})
public final class LoginFromNewDeviceStepConfig extends AbstractFlowStepConfig implements NonInteractiveStepConfig, StepConfigForAuthenticationFlows {
   @PluginProperty(description = "Configures the cookie that stores information about users who have logged in on a device.", optional = false)
   @GroupProperty(groupIdentifier = "Basic Settings")
   private NewDeviceCookieConfig cookieSettings;

   private LoginFromNewDeviceStepConfig(
      NewDeviceCookieConfig cookieSettings,
      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,
      String authenticationMethodId
   ) {
      super(skipCondition, preCondition, requiresActivation, tagsOnSuccess, stepId, onFailureGotos, customResponseAttributes, customFailureResponseAttributes);
      this.cookieSettings = cookieSettings;
   }

   public NewDeviceCookieConfig getCookieSettings() {
      return this.cookieSettings;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class LoginFromNewDeviceStepConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private NewDeviceCookieConfig cookieSettings;
      @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 String authenticationMethodId;

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

      @SuppressFBWarnings(justification = "generated code")
      public LoginFromNewDeviceStepConfig.LoginFromNewDeviceStepConfigBuilder cookieSettings(NewDeviceCookieConfig cookieSettings) {
         this.cookieSettings = cookieSettings;
         return this;
      }

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

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

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

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

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

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

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

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

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

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

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

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

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