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

import com.airlock.iam.admin.api.domain.model.user.AuthenticationMethods;
import com.airlock.iam.admin.domain.model.token.TokenController;
import com.airlock.iam.factor.application.configuration.airlock2fa.Airlock2FASettings;
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.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

@Plugin(displayName = "Airlock 2FA Token Controller", description = "Plugin to manage a user's Airlock 2FA account.")
@PluginLicenseRestriction(moduleAffiliation = "Airlock2FA")
public class Airlock2FATokenControllerConfig implements TokenController {
   public static final String ID = "AIRLOCK_2FA";
   @TokenController.TokenControllerId
   @StringProperty(
      description = "<p>Unique identifier for the token controller. Serves as token type ID in the REST interface.</p>\n<p>This is also the \"auth method\" that is set on the user as active/next authentication method,\ni.e. it must match the \"Authentication Method ID\" of corresponding authentication flow steps.</p>\n<p>Finally, this ID also determines the name (label) of this token controller in the Adminapp UI,\nas defined by the resource key '<tt>user.auth-methods.type.generic.&lt;id&gt;</tt>',\nas well as the label for \"auth method\" specific lock reasons defined by the resource key\n'<tt>user.account-state.LockReason.TooManyAuthAtts.&lt;id&gt;</tt>'.</p>\nPlease note that the length of this ID must not be longer than 22 characters in order to comply with the\ndefault DB schema restrictions for column <tt>lock_reason</tt>.",
      optional = true,
      exampleValues = {"AIRLOCK_2FA", "AIRLOCK_2FA_CUSTOM"},
      displayName = "ID",
      validationRegex = "[a-zA-Z0-9_]+",
      defaultValue = "AIRLOCK_2FA"
   )
   private String id;
   @PluginProperty(
      displayName = "Airlock 2FA Settings",
      description = "Settings of Airlock 2FA.",
      optional = false,
      globalPluginReference = "globalAirlock2FASettings"
   )
   private Airlock2FASettings airlock2faSettings;
   private static final String SETTINGS_CONFIG_FIELD = "airlock2faSettings";
   @PluginProperty(description = "Settings for creating device activation letters. If not configured, activation letters cannot be created.", optional = true)
   private Airlock2FACreateActivationLettersConfig createActivationLetters;
   @PluginProperty(description = "Settings for ordering a device activation letter. If not configured, activation letters cannot be ordered.", optional = true)
   private Airlock2FAOrderActivationLettersConfig orderActivationLetters;
   @PluginProperty(
      displayName = "Create Shipment Letters",
      description = "Settings for hardware token shipment letters. If not configured, shipment letter cannot be created.",
      optional = true
   )
   private Airlock2FAShipmentLettersConfig createShipmentLetters;
   @BooleanProperty(
      displayName = "Assign Hardware Tokens to Multiple Users",
      description = "If checked, a hardware token can be assigned to multiple users.<p>Once a hardware token is assigned to a user, it is only available within the corresponding Futurae service.</p>",
      optional = true,
      defaultValue = "false"
   )
   private boolean shareHardwareTokensAmongUsers;

   public Optional<Airlock2FACreateActivationLettersConfig> getCreateActivationLetters() {
      return Optional.ofNullable(this.createActivationLetters);
   }

   public Optional<Airlock2FAOrderActivationLettersConfig> getOrderActivationLetters() {
      return Optional.ofNullable(this.orderActivationLetters);
   }

   public Optional<Airlock2FAShipmentLettersConfig> getCreateShipmentLetters() {
      return Optional.ofNullable(this.createShipmentLetters);
   }

   @Override
   public AuthenticationMethods.AuthenticationMethodId getConfiguredId() {
      return AuthenticationMethods.AuthenticationMethodId.authMethodId(this.id);
   }

   @Override
   public String getTokenControllerId() {
      return "AIRLOCK_2FA";
   }

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

   public boolean isShareHardwareTokensAmongUsers() {
      return this.shareHardwareTokensAmongUsers;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public Airlock2FATokenControllerConfig(
      String id,
      Airlock2FASettings airlock2faSettings,
      Airlock2FACreateActivationLettersConfig createActivationLetters,
      Airlock2FAOrderActivationLettersConfig orderActivationLetters,
      Airlock2FAShipmentLettersConfig createShipmentLetters,
      boolean shareHardwareTokensAmongUsers
   ) {
      this.id = id;
      this.airlock2faSettings = airlock2faSettings;
      this.createActivationLetters = createActivationLetters;
      this.orderActivationLetters = orderActivationLetters;
      this.createShipmentLetters = createShipmentLetters;
      this.shareHardwareTokensAmongUsers = shareHardwareTokensAmongUsers;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class Airlock2FATokenControllerConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String id;
      @SuppressFBWarnings(justification = "generated code")
      private Airlock2FASettings airlock2faSettings;
      @SuppressFBWarnings(justification = "generated code")
      private Airlock2FACreateActivationLettersConfig createActivationLetters;
      @SuppressFBWarnings(justification = "generated code")
      private Airlock2FAOrderActivationLettersConfig orderActivationLetters;
      @SuppressFBWarnings(justification = "generated code")
      private Airlock2FAShipmentLettersConfig createShipmentLetters;
      @SuppressFBWarnings(justification = "generated code")
      private boolean shareHardwareTokensAmongUsers;

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FATokenControllerConfig.Airlock2FATokenControllerConfigBuilder id(String id) {
         this.id = id;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FATokenControllerConfig.Airlock2FATokenControllerConfigBuilder createActivationLetters(
         Airlock2FACreateActivationLettersConfig createActivationLetters
      ) {
         this.createActivationLetters = createActivationLetters;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FATokenControllerConfig.Airlock2FATokenControllerConfigBuilder orderActivationLetters(
         Airlock2FAOrderActivationLettersConfig orderActivationLetters
      ) {
         this.orderActivationLetters = orderActivationLetters;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FATokenControllerConfig.Airlock2FATokenControllerConfigBuilder createShipmentLetters(Airlock2FAShipmentLettersConfig createShipmentLetters) {
         this.createShipmentLetters = createShipmentLetters;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FATokenControllerConfig.Airlock2FATokenControllerConfigBuilder shareHardwareTokensAmongUsers(boolean shareHardwareTokensAmongUsers) {
         this.shareHardwareTokensAmongUsers = shareHardwareTokensAmongUsers;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Airlock2FATokenControllerConfig build() {
         return new Airlock2FATokenControllerConfig(
            this.id,
            this.airlock2faSettings,
            this.createActivationLetters,
            this.orderActivationLetters,
            this.createShipmentLetters,
            this.shareHardwareTokensAmongUsers
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "Airlock2FATokenControllerConfig.Airlock2FATokenControllerConfigBuilder(id="
            + this.id
            + ", airlock2faSettings="
            + this.airlock2faSettings
            + ", createActivationLetters="
            + this.createActivationLetters
            + ", orderActivationLetters="
            + this.orderActivationLetters
            + ", createShipmentLetters="
            + this.createShipmentLetters
            + ", shareHardwareTokensAmongUsers="
            + this.shareHardwareTokensAmongUsers
            + ")";
      }
   }
}
