package com.airlock.iam.login.app.application.configuration.oauth;

import com.airlock.iam.common.api.application.configuration.credential.RequestAuthenticationConfigForLoginapp;
import com.airlock.iam.common.application.configuration.credential.BaseRequestAuthenticationConfig;
import com.airlock.iam.common.application.configuration.oauth2.OAuth2ASIdentifierConfig;
import com.airlock.iam.core.application.configuration.store.user.UserStoreProvider;
import com.airlock.iam.core.misc.authen.UsernameTransformer;
import com.airlock.iam.oauth2.api.domain.model.AuthorizationServerId;
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.BooleanProperty;
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 java.util.Collections;
import java.util.List;

@Plugin(
   description = "Extracts an OAuth 2.0 access token (bearer token) from a request to authenticate single requests.",
   displayName = "OAuth 2.0 Token Request Authentication"
)
@Groups(openGroups = "Basic Settings", groupSequence = {"Basic Settings", "Advanced Settings"})
public final class OAuth2TokenRequestAuthenticationConfig extends BaseRequestAuthenticationConfig implements RequestAuthenticationConfigForLoginapp {
   @PluginProperty(
      description = "<p>The unique identifier of the OAuth 2.0 Authorization Server.</p><p>This must reference an Authorization Server in the top-level OAuth 2.0 Settings of the Loginapp.</p>",
      displayName = "Authorization Server ID",
      optional = false
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private OAuth2ASIdentifierConfig authorizationServerId;
   @BooleanProperty(
      description = "If enabled, the scopes from the Access Token are added as roles to the authenticated user.",
      optional = true,
      defaultValue = "true"
   )
   @GroupProperty(groupIdentifier = "Basic Settings")
   private boolean addScopesAsRoles;
   private final List<UsernameTransformer> usernameTransformers = Collections.emptyList();

   private OAuth2TokenRequestAuthenticationConfig(
      UserStoreProvider userStore,
      List<String> staticRoles,
      List<String> rolesBlocklist,
      OAuth2ASIdentifierConfig authorizationServerId,
      boolean addScopesAsRoles
   ) {
      super(userStore, Collections.emptyList(), staticRoles, rolesBlocklist);
      this.authorizationServerId = authorizationServerId;
      this.addScopesAsRoles = addScopesAsRoles;
   }

   public AuthorizationServerId getAuthorizationServerId() {
      return AuthorizationServerId.authorizationServerId(this.authorizationServerId.getIdentifier());
   }

   public boolean isAddScopesAsRoles() {
      return this.addScopesAsRoles;
   }

   @Override
   public List<UsernameTransformer> getUsernameTransformers() {
      return Collections.emptyList();
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2TokenRequestAuthenticationConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private UserStoreProvider userStore;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> staticRoles;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> rolesBlocklist;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ASIdentifierConfig authorizationServerId;
      @SuppressFBWarnings(justification = "generated code")
      private boolean addScopesAsRoles;

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

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2TokenRequestAuthenticationConfig.OAuth2TokenRequestAuthenticationConfigBuilder authorizationServerId(
         OAuth2ASIdentifierConfig authorizationServerId
      ) {
         this.authorizationServerId = authorizationServerId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2TokenRequestAuthenticationConfig.OAuth2TokenRequestAuthenticationConfigBuilder addScopesAsRoles(boolean addScopesAsRoles) {
         this.addScopesAsRoles = addScopesAsRoles;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2TokenRequestAuthenticationConfig build() {
         return new OAuth2TokenRequestAuthenticationConfig(
            this.userStore, this.staticRoles, this.rolesBlocklist, this.authorizationServerId, this.addScopesAsRoles
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2TokenRequestAuthenticationConfig.OAuth2TokenRequestAuthenticationConfigBuilder(userStore="
            + this.userStore
            + ", staticRoles="
            + this.staticRoles
            + ", rolesBlocklist="
            + this.rolesBlocklist
            + ", authorizationServerId="
            + this.authorizationServerId
            + ", addScopesAsRoles="
            + this.addScopesAsRoles
            + ")";
      }
   }
}
