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

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.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.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.annotation.property.StringProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Map;

public abstract class CommonCrontoCheckingStepConfig extends AbstractInteractiveFlowStepConfig {
   @PluginProperty(
      description = "<p>Handles all Cronto-specific actions.</p><p>When the Cronto app communicates directly to IAM (for online validation and push notification management) these requests are on a separate session and must therefore be handled by a separate, global Cronto Handler defined in \"Cronto App Communication\" in Loginapp.</p>",
      globalPluginReference = "globalCrontoSettings",
      optional = false
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private CrontoHandler crontoHandler;
   protected static final String FIELD_CRONTO_HANDLER = "crontoHandler";
   @StringProperty(
      description = "The identifier of the authentication method for this step. Since the authentication method is also the identifier for failed login attempts for this step, distinct identifiers must be chosen if multiple instances of the same step type are used to check different credentials (e.g., two password step instances check two different passwords).<p>Example: a system tracks two passwords per user. Password 1 is used in flow A, password 2 in flow B. These two steps must have distinct 'Authentication Method Ids', e.g. PASSWORD1 and PASSWORD2.</p>If only one identifier (e.g. \"PASSWORD\") is used, this may allow brute force attacks on the password as follows. Assuming an attacker knows the user's password 1, they get an unlimited number of attempts on flow B, as the 'PASSWORD' counter can repeatedly be reset to 0 by performing a successful login on flow A.<p>To prevent such attacks, use two different counters by setting the authentication methods, for example, to PASSWORD1 and PASSWORD2, respectively.</p>",
      displayName = "Authentication Method ID",
      defaultValue = "CRONTO",
      maxLength = 23,
      optional = true
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private String authenticationMethodId;
   @IntegerProperty(
      description = "<p>The number of times the user may enter a wrong response before the flow is aborted\n(and the challenge is deleted). If set to 0, only 1 attempt is possible for each challenge.</p>\n<p>The purpose of this settings is usability. The failed attempts counter is always increased upon\nreceiving a wrong OTP and the user is locked when the global failed attempts limit is exceeded.</p>",
      minValue = 0,
      defaultValue = 3,
      optional = true,
      exampleValues = {0, 3, 5}
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private int maxResponseRetries;

   protected CommonCrontoCheckingStepConfig(
      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
      );
      this.crontoHandler = crontoHandler;
      this.authenticationMethodId = authenticationMethodId;
      this.maxResponseRetries = maxResponseRetries;
   }

   public CrontoHandler getCrontoHandler() {
      return this.crontoHandler;
   }

   public String getAuthenticationMethodId() {
      return this.authenticationMethodId;
   }

   public int getMaxResponseRetries() {
      return this.maxResponseRetries;
   }

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