package com.airlock.iam.oauth2.infrastructure.discovery.compatibility;

import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public final class OpenIDConnectCompatibility {
   private static final List<OpenIDConnectConfiguration> DEFAULT_CONFIGURATIONS = List.of(
      new OpenIDConnectConfigurationAuthorizationURI(),
      new OpenIDConnectConfigurationTokenEndpointURI(),
      new OpenIDConnectConfigurationResponseTypes(),
      new OpenIDConnectConfigurationResponseModes(),
      new OpenIDConnectConfigurationGrantTypes(),
      new OpenIDConnectConfigurationIdTokenSigningAlgorithms()
   );
   private final List<OpenIDConnectConfiguration> configurations;
   private final OIDCProviderMetadata metadata;

   private OpenIDConnectCompatibility(OIDCProviderMetadata metadata, List<OpenIDConnectConfiguration> configurations) {
      this.metadata = metadata;
      ArrayList<OpenIDConnectConfiguration> configs = new ArrayList<>(configurations);
      configs.addAll(DEFAULT_CONFIGURATIONS);
      this.configurations = List.copyOf(configs);
   }

   public OpenIDConnectCompatibilityResult validate() {
      OpenIDConnectCompatibilityResult result = OpenIDConnectCompatibilityResult.SUCCESS;

      for (OpenIDConnectConfiguration configuration : this.configurations) {
         result = result.merged(configuration.validate(this.metadata));
      }

      return result;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OpenIDConnectCompatibilityBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private OIDCProviderMetadata metadata;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<OpenIDConnectConfiguration> configurations;

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibility.OpenIDConnectCompatibilityBuilder metadata(OIDCProviderMetadata metadata) {
         this.metadata = metadata;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibility.OpenIDConnectCompatibilityBuilder configuration(OpenIDConnectConfiguration configuration) {
         if (this.configurations == null) {
            this.configurations = new ArrayList<>();
         }

         this.configurations.add(configuration);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibility.OpenIDConnectCompatibilityBuilder configurations(Collection<? extends OpenIDConnectConfiguration> configurations) {
         if (configurations == null) {
            throw new NullPointerException("configurations cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectCompatibility.OpenIDConnectCompatibilityBuilder clearConfigurations() {
         if (this.configurations != null) {
            this.configurations.clear();
         }

         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OpenIDConnectCompatibility.OpenIDConnectCompatibilityBuilder(metadata=" + this.metadata + ", configurations=" + this.configurations + ")";
      }
   }
}
