package com.airlock.iam.login.app.misc.configuration;

import com.airlock.iam.login.app.misc.configuration.oauth.as.OAuth2ASConfig;
import com.airlock.iam.oauth2.api.domain.model.AuthorizationServerId;
import com.airlock.iam.oauth2.application.configuration.OAuth2AsConfigsSpec;
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.config.ConfigurationContext;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Plugin(description = "Configuration for all OAuth 2.0 Authorization Servers.", displayName = "OAuth 2.0/OIDC Authorization Servers")
@PluginLicenseRestriction(moduleAffiliation = "OAuthServer")
public class OAuth2AuthorizationServersConfig implements OAuth2AsConfigsSpec {
   @PluginListProperty(
      displayName = "Authorization Servers",
      description = "The list of configured Authorization Servers (AS).",
      optional = false,
      minElements = 1
   )
   private List<OAuth2ASConfig> authorizationServers;
   public static final String AS_DISPLAY_NAME = "Authorization Servers";

   public static Optional<OAuth2ASConfig> getASConfigById(AuthorizationServerId id, ConfigurationContext ctx) {
      return Loginapp.get(ctx)
         .getOAuth2ASSettings()
         .map(OAuth2AuthorizationServersConfig::getOAuth2AuthorizationServerConfigSpecs)
         .orElse(Collections.emptyList())
         .stream()
         .filter(s -> s.getOAuth2ASIdentifier().equals(id))
         .findFirst();
   }

   @Override
   public Collection<OAuth2ASConfig> getOAuth2AuthorizationServerConfigSpecs() {
      return this.authorizationServers;
   }

   @Override
   public Optional<OAuth2ASConfig> findOAuth2AuthorizationServerConfigSpec(AuthorizationServerId authorizationServerId) {
      return this.authorizationServers.stream().filter(config -> config.getOAuth2ASIdentifier().equals(authorizationServerId)).findFirst();
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2AuthorizationServersConfig(List<OAuth2ASConfig> authorizationServers) {
      this.authorizationServers = authorizationServers;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2AuthorizationServersConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<OAuth2ASConfig> authorizationServers;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2AuthorizationServersConfig.OAuth2AuthorizationServersConfigBuilder authorizationServer(OAuth2ASConfig authorizationServer) {
         if (this.authorizationServers == null) {
            this.authorizationServers = new ArrayList<>();
         }

         this.authorizationServers.add(authorizationServer);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2AuthorizationServersConfig.OAuth2AuthorizationServersConfigBuilder authorizationServers(
         Collection<? extends OAuth2ASConfig> authorizationServers
      ) {
         if (authorizationServers == null) {
            throw new NullPointerException("authorizationServers cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2AuthorizationServersConfig.OAuth2AuthorizationServersConfigBuilder clearAuthorizationServers() {
         if (this.authorizationServers != null) {
            this.authorizationServers.clear();
         }

         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2AuthorizationServersConfig.OAuth2AuthorizationServersConfigBuilder(authorizationServers=" + this.authorizationServers + ")";
      }
   }
}
