package com.airlock.iam.oauth2.application.configuration.session;

import com.airlock.iam.oauth2.application.configuration.OAuth2BearerAccessTokenConfig;
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.PluginListProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

@Plugin(
   description = "Configuration for the OAuth 2.0 / OpenID Connect Session Management Endpoint where users can list, delete or modify their current OAuth 2.0 / OpenID Connect sessions.",
   displayName = "OAuth 2.0 Session Management Endpoint"
)
@PluginLicenseRestriction(moduleAffiliation = "OAuthServer")
public class OAuth2SessionManagementEndpointConfig {
   @PluginProperty(
      description = "Plugin defining how the Access Token is extracted from the request header.",
      defaultValue = OAuth2BearerAccessTokenConfig.class,
      optional = true
   )
   private OAuth2BearerAccessTokenConfig accessTokenConfig;
   @PluginListProperty(
      description = "List of allowed OAuth 2.0 custom session attributes. This endpoint can only add or modify custom session attributes listed here.",
      optional = true
   )
   private List<OAuth2CustomSessionAttributeConfig> customSessionAttributes;

   public OAuth2BearerAccessTokenConfig getAccessTokenConfig() {
      return this.accessTokenConfig;
   }

   public List<OAuth2CustomSessionAttributeConfig> getCustomSessionAttributes() {
      return this.customSessionAttributes;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2SessionManagementEndpointConfig(
      OAuth2BearerAccessTokenConfig accessTokenConfig, List<OAuth2CustomSessionAttributeConfig> customSessionAttributes
   ) {
      this.accessTokenConfig = accessTokenConfig;
      this.customSessionAttributes = customSessionAttributes;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2SessionManagementEndpointConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2BearerAccessTokenConfig accessTokenConfig;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<OAuth2CustomSessionAttributeConfig> customSessionAttributes;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionManagementEndpointConfig.OAuth2SessionManagementEndpointConfigBuilder accessTokenConfig(
         OAuth2BearerAccessTokenConfig accessTokenConfig
      ) {
         this.accessTokenConfig = accessTokenConfig;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionManagementEndpointConfig.OAuth2SessionManagementEndpointConfigBuilder customSessionAttribute(
         OAuth2CustomSessionAttributeConfig customSessionAttribute
      ) {
         if (this.customSessionAttributes == null) {
            this.customSessionAttributes = new ArrayList<>();
         }

         this.customSessionAttributes.add(customSessionAttribute);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionManagementEndpointConfig.OAuth2SessionManagementEndpointConfigBuilder customSessionAttributes(
         Collection<? extends OAuth2CustomSessionAttributeConfig> customSessionAttributes
      ) {
         if (customSessionAttributes == null) {
            throw new NullPointerException("customSessionAttributes cannot be null");
         }

         if (this.customSessionAttributes == null) {
            this.customSessionAttributes = new ArrayList<>();
         }

         this.customSessionAttributes.addAll(customSessionAttributes);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionManagementEndpointConfig.OAuth2SessionManagementEndpointConfigBuilder clearCustomSessionAttributes() {
         if (this.customSessionAttributes != null) {
            this.customSessionAttributes.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2SessionManagementEndpointConfig build() {
         return new OAuth2SessionManagementEndpointConfig(
            this.accessTokenConfig, switch (this.customSessionAttributes == null ? 0 : this.customSessionAttributes.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.customSessionAttributes.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.customSessionAttributes));
            }
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2SessionManagementEndpointConfig.OAuth2SessionManagementEndpointConfigBuilder(accessTokenConfig="
            + this.accessTokenConfig
            + ", customSessionAttributes="
            + this.customSessionAttributes
            + ")";
      }
   }
}
