package com.airlock.iam.common.application.configuration.credential;

import com.airlock.iam.common.api.application.configuration.credential.RequestAuthenticationConfigForAdminapp;
import com.airlock.iam.common.api.application.configuration.credential.RequestAuthenticationConfigForLoginapp;
import com.airlock.iam.common.api.application.configuration.credential.RequestAuthenticationConfigForTransactionApproval;
import com.airlock.iam.core.application.configuration.store.user.UserStoreProvider;
import com.airlock.iam.core.misc.authen.PasswordPolicy;
import com.airlock.iam.core.misc.authen.UsernameTransformer;
import com.airlock.iam.core.misc.impl.authen.NullPasswordPolicy;
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.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 java.util.List;
import java.util.OptionalInt;

@Plugin(description = "Authenticates single requests with HTTP Basic Authentication.", displayName = "Basic Auth Request Authentication")
@Groups(groupSequence = {"Basic Settings", "Advanced Settings"}, openGroups = "Basic Settings")
public final class BasicAuthRequestAuthenticationConfig
   extends BaseRequestAuthenticationConfig
   implements RequestAuthenticationConfigForAdminapp,
   RequestAuthenticationConfigForLoginapp,
   RequestAuthenticationConfigForTransactionApproval {
   @PluginProperty(description = "The repository of user passwords.", displayName = "Password Repository", optional = false)
   @GroupProperty(groupIdentifier = "Basic Settings")
   private PasswordRepositoryConfigForRequestAuthentication passwordRepository;
   public static final String PASSWORD_REPOSITORY_DISPLAY_NAME = "Password Repository";
   @PluginProperty(
      description = "The password policy that is checked when authenticating. Authentication fails if password policies are violated.",
      optional = true,
      defaultValue = NullPasswordPolicy.class
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private PasswordPolicy policyToCheckOnLogin;
   @IntegerProperty(
      description = "The maximum number of failed authentication attempts before the user is locked.<p>Effective only if a 'User Store' is configured.</p>",
      defaultValue = 5,
      optional = true
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private int maxFailedAttempts;
   @StringProperty(
      description = "The character set to use for decoding 'Authorization' headers.",
      defaultValue = "UTF-8",
      suggestedValues = {"ISO-8859-1", "UTF-8"},
      optional = true
   )
   @GroupProperty(groupIdentifier = "Advanced Settings")
   private String charsetName;

   public BasicAuthRequestAuthenticationConfig(
      PasswordRepositoryConfigForRequestAuthentication passwordRepository,
      PasswordPolicy policyToCheckOnLogin,
      Integer maxFailedAttempts,
      String charsetName,
      UserStoreProvider userStore,
      List<UsernameTransformer> usernameTransformers,
      List<String> staticRoles,
      List<String> rolesBlocklist
   ) {
      super(userStore, usernameTransformers, staticRoles, rolesBlocklist);
      this.passwordRepository = passwordRepository;
      this.policyToCheckOnLogin = policyToCheckOnLogin;
      this.maxFailedAttempts = maxFailedAttempts;
      this.charsetName = charsetName;
   }

   @Override
   public OptionalInt getMaxFailedAttempts() {
      return OptionalInt.of(this.maxFailedAttempts);
   }

   public PasswordRepositoryConfigForRequestAuthentication getPasswordRepository() {
      return this.passwordRepository;
   }

   public PasswordPolicy getPolicyToCheckOnLogin() {
      return this.policyToCheckOnLogin;
   }

   public String getCharsetName() {
      return this.charsetName;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class BasicAuthRequestAuthenticationConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private PasswordRepositoryConfigForRequestAuthentication passwordRepository;
      @SuppressFBWarnings(justification = "generated code")
      private PasswordPolicy policyToCheckOnLogin;
      @SuppressFBWarnings(justification = "generated code")
      private Integer maxFailedAttempts;
      @SuppressFBWarnings(justification = "generated code")
      private String charsetName;
      @SuppressFBWarnings(justification = "generated code")
      private UserStoreProvider userStore;
      @SuppressFBWarnings(justification = "generated code")
      private List<UsernameTransformer> usernameTransformers;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> staticRoles;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> rolesBlocklist;

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

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder passwordRepository(
         PasswordRepositoryConfigForRequestAuthentication passwordRepository
      ) {
         this.passwordRepository = passwordRepository;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder policyToCheckOnLogin(PasswordPolicy policyToCheckOnLogin) {
         this.policyToCheckOnLogin = policyToCheckOnLogin;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder maxFailedAttempts(Integer maxFailedAttempts) {
         this.maxFailedAttempts = maxFailedAttempts;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder charsetName(String charsetName) {
         this.charsetName = charsetName;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder userStore(UserStoreProvider userStore) {
         this.userStore = userStore;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder usernameTransformers(
         List<UsernameTransformer> usernameTransformers
      ) {
         this.usernameTransformers = usernameTransformers;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder staticRoles(List<String> staticRoles) {
         this.staticRoles = staticRoles;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder rolesBlocklist(List<String> rolesBlocklist) {
         this.rolesBlocklist = rolesBlocklist;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public BasicAuthRequestAuthenticationConfig build() {
         return new BasicAuthRequestAuthenticationConfig(
            this.passwordRepository,
            this.policyToCheckOnLogin,
            this.maxFailedAttempts,
            this.charsetName,
            this.userStore,
            this.usernameTransformers,
            this.staticRoles,
            this.rolesBlocklist
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "BasicAuthRequestAuthenticationConfig.BasicAuthRequestAuthenticationConfigBuilder(passwordRepository="
            + this.passwordRepository
            + ", policyToCheckOnLogin="
            + this.policyToCheckOnLogin
            + ", maxFailedAttempts="
            + this.maxFailedAttempts
            + ", charsetName="
            + this.charsetName
            + ", userStore="
            + this.userStore
            + ", usernameTransformers="
            + this.usernameTransformers
            + ", staticRoles="
            + this.staticRoles
            + ", rolesBlocklist="
            + this.rolesBlocklist
            + ")";
      }
   }
}
