package com.airlock.iam.login.rest.application.configuration;

import com.airlock.iam.core.misc.cronto.CrontoHandler;
import com.airlock.iam.plugin.api.annotation.config.DeprecatedPlugin;
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.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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

@Plugin(description = "Configures the Cronto device management REST self-service.", displayName = "Cronto Self-Services (Legacy)")
@DeprecatedPlugin(
   description = "The session-less Cronto self-service endpoints are deprecated and will be removed in a future IAM version. Use protected self-service flows instead."
)
@Groups(groupSequence = {"Basic Settings", "Letter Settings", "Advanced Settings"}, openGroups = "Basic Settings")
@PluginLicenseRestriction(moduleAffiliation = "Cronto")
public class CrontoSelfServiceRestConfig {
   public static final String LETTER_SETTINGS = "Letter Settings";
   @PluginProperty(
      description = "Manages the organization of the different Cronto tokens as well as the calls to the Cronto engine. This is usually the same handler as used by the Cronto authenticator.",
      optional = false,
      globalPluginReference = "globalCrontoSettings"
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private CrontoHandler crontoHandler;
   @BooleanProperty(
      description = "If this option is checked, a user may disable all his Cronto devices in the Cronto device management.",
      optional = true,
      defaultValue = "false"
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private boolean userCanDisableAllDevices;
   @IntegerProperty(
      description = "The maximum allowed time (in seconds) between the first REST call for adding a new Cronto device, and the second call that verifies the OTP from the first call.",
      displayName = "Activation Session Lifetime [s]",
      optional = true,
      minValue = 1,
      defaultValue = 120,
      exampleValues = {60, 3000}
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private int activationSessionLifetime;
   @BooleanProperty(
      description = "<p>If this option is activated, users can order an additional activation letter, given they have already received a letter but need a new one.</p> <p>The letter can be ordered on the activation page and the device management page.</p>",
      optional = true,
      defaultValue = "false"
   )
   @GroupProperty(groupIdentifier = "Letter Settings")
   private Boolean userCanOrderAdditionalLetter;
   @IntegerProperty(
      description = "<p>Number of hours that must at least have passed since the last Cronto activation letter has been ordered. This is only used if \"User can order additional letter\" is activated.</p><p><strong>Note:</strong>By setting this value to 0, no waiting time until an additional letter can be ordered is required. However, it is recommended to set a different value to prevent a letter being ordered while another one is still being printed or being delivered.</p>",
      optional = true,
      minValue = 0,
      defaultValue = 24,
      exampleValues = {12, 24, 48}
   )
   @GroupProperty(groupIdentifier = "Letter Settings")
   private int minimalNewLetterIntervalInHours;
   @BooleanProperty(
      description = "If enabled, a deactivation challenge is provided after deleting a device. This challenge is used to remove the account from the app.",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private boolean provideDeactivationChallenge;

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

   public boolean isUserCanDisableAllDevices() {
      return this.userCanDisableAllDevices;
   }

   public int getActivationSessionLifetime() {
      return this.activationSessionLifetime;
   }

   public Boolean getUserCanOrderAdditionalLetter() {
      return this.userCanOrderAdditionalLetter;
   }

   public int getMinimalNewLetterIntervalInHours() {
      return this.minimalNewLetterIntervalInHours;
   }

   public boolean isProvideDeactivationChallenge() {
      return this.provideDeactivationChallenge;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public CrontoSelfServiceRestConfig(
      CrontoHandler crontoHandler,
      boolean userCanDisableAllDevices,
      int activationSessionLifetime,
      Boolean userCanOrderAdditionalLetter,
      int minimalNewLetterIntervalInHours,
      boolean provideDeactivationChallenge
   ) {
      this.crontoHandler = crontoHandler;
      this.userCanDisableAllDevices = userCanDisableAllDevices;
      this.activationSessionLifetime = activationSessionLifetime;
      this.userCanOrderAdditionalLetter = userCanOrderAdditionalLetter;
      this.minimalNewLetterIntervalInHours = minimalNewLetterIntervalInHours;
      this.provideDeactivationChallenge = provideDeactivationChallenge;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class CrontoSelfServiceRestConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private CrontoHandler crontoHandler;
      @SuppressFBWarnings(justification = "generated code")
      private boolean userCanDisableAllDevices;
      @SuppressFBWarnings(justification = "generated code")
      private int activationSessionLifetime;
      @SuppressFBWarnings(justification = "generated code")
      private Boolean userCanOrderAdditionalLetter;
      @SuppressFBWarnings(justification = "generated code")
      private int minimalNewLetterIntervalInHours;
      @SuppressFBWarnings(justification = "generated code")
      private boolean provideDeactivationChallenge;

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

      @SuppressFBWarnings(justification = "generated code")
      public CrontoSelfServiceRestConfig.CrontoSelfServiceRestConfigBuilder crontoHandler(CrontoHandler crontoHandler) {
         this.crontoHandler = crontoHandler;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoSelfServiceRestConfig.CrontoSelfServiceRestConfigBuilder userCanDisableAllDevices(boolean userCanDisableAllDevices) {
         this.userCanDisableAllDevices = userCanDisableAllDevices;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoSelfServiceRestConfig.CrontoSelfServiceRestConfigBuilder activationSessionLifetime(int activationSessionLifetime) {
         this.activationSessionLifetime = activationSessionLifetime;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoSelfServiceRestConfig.CrontoSelfServiceRestConfigBuilder userCanOrderAdditionalLetter(Boolean userCanOrderAdditionalLetter) {
         this.userCanOrderAdditionalLetter = userCanOrderAdditionalLetter;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoSelfServiceRestConfig.CrontoSelfServiceRestConfigBuilder minimalNewLetterIntervalInHours(int minimalNewLetterIntervalInHours) {
         this.minimalNewLetterIntervalInHours = minimalNewLetterIntervalInHours;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoSelfServiceRestConfig.CrontoSelfServiceRestConfigBuilder provideDeactivationChallenge(boolean provideDeactivationChallenge) {
         this.provideDeactivationChallenge = provideDeactivationChallenge;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public CrontoSelfServiceRestConfig build() {
         return new CrontoSelfServiceRestConfig(
            this.crontoHandler,
            this.userCanDisableAllDevices,
            this.activationSessionLifetime,
            this.userCanOrderAdditionalLetter,
            this.minimalNewLetterIntervalInHours,
            this.provideDeactivationChallenge
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "CrontoSelfServiceRestConfig.CrontoSelfServiceRestConfigBuilder(crontoHandler="
            + this.crontoHandler
            + ", userCanDisableAllDevices="
            + this.userCanDisableAllDevices
            + ", activationSessionLifetime="
            + this.activationSessionLifetime
            + ", userCanOrderAdditionalLetter="
            + this.userCanOrderAdditionalLetter
            + ", minimalNewLetterIntervalInHours="
            + this.minimalNewLetterIntervalInHours
            + ", provideDeactivationChallenge="
            + this.provideDeactivationChallenge
            + ")";
      }
   }
}
