package com.airlock.iam.oauth2.domain.model.metadata;

import com.airlock.iam.oauth2.api.domain.model.clientauthentication.ClientAuthenticationMethod;
import com.airlock.iam.oauth2.domain.model.Issuer;
import com.airlock.iam.oauth2.domain.model.OAuth2IssuerValidationMode;
import com.airlock.iam.oauth2.domain.model.PkceCodeChallengeMethod;
import com.airlock.iam.oauth2.domain.model.acr.OpenIdConnectAcrValue;
import com.airlock.iam.oauth2.domain.model.authorization.OAuth2ResponseType;
import com.airlock.iam.oauth2.domain.model.claims.ClaimType;
import com.airlock.iam.oauth2.domain.model.settings.OAuth2SupportedResponseModes;
import com.nimbusds.jose.JWSAlgorithm;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import lombok.NonNull;

public class OAuth2MetadataSettings {
   private final Issuer issuer;
   private final OAuth2IssuerValidationMode issuerValidationMode;
   private final boolean authorizationCodeGrantSupported;
   private final boolean clientCredentialsGrantSupported;
   private final boolean tokenExchangeGrantSupported;
   private final boolean generateRefreshToken;
   private final OAuth2MetadataSettings.OpenIDConnectSettings openIDConnectSettings;
   private final PkceCodeChallengeMethod pkceCodeChallengeMethod;
   private final OAuth2MetadataSettings.RegistrationEndpointSettings registrationEndpointSettings;
   private final OAuth2MetadataSettings.JwksEndpointSettings jwksEndpointSettings;
   private final OAuth2MetadataSettings.AuthorizationEndpointSettings authorizationEndpointSettings;
   private final OAuth2MetadataSettings.TokenEndpointSettings tokenEndpointSettings;
   private final OAuth2MetadataSettings.PushedAuthorizationRequestEndpointSettings pushedAuthorizationRequestEndpointSettings;
   private final OAuth2MetadataSettings.TokenRevocationEndpointSettings tokenRevocationEndpointSettings;
   private final OAuth2MetadataSettings.TokenIntrospectionEndpointSettings tokenIntrospectionEndpointSettings;
   private final OAuth2MetadataSettings.UserInfoEndpointSettings userInfoEndpointSettings;
   private final boolean checkSessionSupported;
   private final List<UILocale> uiLocales;
   @NonNull
   private final OAuth2SupportedResponseModes supportedResponseModes;
   private final boolean backChannelLogoutSupported;

   public Optional<OAuth2MetadataSettings.OpenIDConnectSettings> openIDConnectSettings() {
      return Optional.ofNullable(this.openIDConnectSettings);
   }

   public Optional<PkceCodeChallengeMethod> pkceCodeChallengeMethod() {
      return Optional.ofNullable(this.pkceCodeChallengeMethod);
   }

   public Optional<OAuth2MetadataSettings.RegistrationEndpointSettings> registrationEndpointSettings() {
      return Optional.ofNullable(this.registrationEndpointSettings);
   }

   public Optional<OAuth2MetadataSettings.JwksEndpointSettings> jwksEndpointSettings() {
      return Optional.ofNullable(this.jwksEndpointSettings);
   }

   public Optional<OAuth2MetadataSettings.AuthorizationEndpointSettings> authorizationEndpointSettings() {
      return Optional.ofNullable(this.authorizationEndpointSettings);
   }

   public Optional<OAuth2MetadataSettings.TokenEndpointSettings> tokenEndpointSettings() {
      return Optional.ofNullable(this.tokenEndpointSettings);
   }

   public Optional<OAuth2MetadataSettings.PushedAuthorizationRequestEndpointSettings> pushedAuthorizationRequestEndpointSettings() {
      return Optional.ofNullable(this.pushedAuthorizationRequestEndpointSettings);
   }

   public Optional<OAuth2MetadataSettings.TokenRevocationEndpointSettings> tokenRevocationEndpointSettings() {
      return Optional.ofNullable(this.tokenRevocationEndpointSettings);
   }

   public Optional<OAuth2MetadataSettings.TokenIntrospectionEndpointSettings> tokenIntrospectionEndpointSettings() {
      return Optional.ofNullable(this.tokenIntrospectionEndpointSettings);
   }

   public Optional<OAuth2MetadataSettings.UserInfoEndpointSettings> userInfoEndpointSettings() {
      return Optional.ofNullable(this.userInfoEndpointSettings);
   }

   public static OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder builder(Issuer issuer) {
      return new OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder()
         .issuer(issuer)
         .issuerValidationMode(OAuth2IssuerValidationMode.IGNORE)
         .supportedResponseModes(OAuth2SupportedResponseModes.builder().build());
   }

   public List<UILocale> uiLocales() {
      return this.uiLocales;
   }

   public boolean isBackChannelLogoutSupported() {
      return this.backChannelLogoutSupported;
   }

   @SuppressFBWarnings(justification = "generated code")
   OAuth2MetadataSettings(
      Issuer issuer,
      OAuth2IssuerValidationMode issuerValidationMode,
      boolean authorizationCodeGrantSupported,
      boolean clientCredentialsGrantSupported,
      boolean tokenExchangeGrantSupported,
      boolean generateRefreshToken,
      OAuth2MetadataSettings.OpenIDConnectSettings openIDConnectSettings,
      PkceCodeChallengeMethod pkceCodeChallengeMethod,
      OAuth2MetadataSettings.RegistrationEndpointSettings registrationEndpointSettings,
      OAuth2MetadataSettings.JwksEndpointSettings jwksEndpointSettings,
      OAuth2MetadataSettings.AuthorizationEndpointSettings authorizationEndpointSettings,
      OAuth2MetadataSettings.TokenEndpointSettings tokenEndpointSettings,
      OAuth2MetadataSettings.PushedAuthorizationRequestEndpointSettings pushedAuthorizationRequestEndpointSettings,
      OAuth2MetadataSettings.TokenRevocationEndpointSettings tokenRevocationEndpointSettings,
      OAuth2MetadataSettings.TokenIntrospectionEndpointSettings tokenIntrospectionEndpointSettings,
      OAuth2MetadataSettings.UserInfoEndpointSettings userInfoEndpointSettings,
      boolean checkSessionSupported,
      List<UILocale> uiLocales,
      @NonNull OAuth2SupportedResponseModes supportedResponseModes,
      boolean backChannelLogoutSupported
   ) {
      if (supportedResponseModes == null) {
         throw new NullPointerException("supportedResponseModes is marked non-null but is null");
      }

      this.issuer = issuer;
      this.issuerValidationMode = issuerValidationMode;
      this.authorizationCodeGrantSupported = authorizationCodeGrantSupported;
      this.clientCredentialsGrantSupported = clientCredentialsGrantSupported;
      this.tokenExchangeGrantSupported = tokenExchangeGrantSupported;
      this.generateRefreshToken = generateRefreshToken;
      this.openIDConnectSettings = openIDConnectSettings;
      this.pkceCodeChallengeMethod = pkceCodeChallengeMethod;
      this.registrationEndpointSettings = registrationEndpointSettings;
      this.jwksEndpointSettings = jwksEndpointSettings;
      this.authorizationEndpointSettings = authorizationEndpointSettings;
      this.tokenEndpointSettings = tokenEndpointSettings;
      this.pushedAuthorizationRequestEndpointSettings = pushedAuthorizationRequestEndpointSettings;
      this.tokenRevocationEndpointSettings = tokenRevocationEndpointSettings;
      this.tokenIntrospectionEndpointSettings = tokenIntrospectionEndpointSettings;
      this.userInfoEndpointSettings = userInfoEndpointSettings;
      this.checkSessionSupported = checkSessionSupported;
      this.uiLocales = uiLocales;
      this.supportedResponseModes = supportedResponseModes;
      this.backChannelLogoutSupported = backChannelLogoutSupported;
   }

   @SuppressFBWarnings(justification = "generated code")
   public Issuer issuer() {
      return this.issuer;
   }

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2IssuerValidationMode issuerValidationMode() {
      return this.issuerValidationMode;
   }

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

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

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

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

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

   @NonNull
   @SuppressFBWarnings(justification = "generated code")
   public OAuth2SupportedResponseModes supportedResponseModes() {
      return this.supportedResponseModes;
   }

   public static final class AuthorizationEndpointSettings {
      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         return o == this ? true : o instanceof OAuth2MetadataSettings.AuthorizationEndpointSettings;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int result = 1;
         return 1;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.AuthorizationEndpointSettings()";
      }
   }

   public static final class JwksEndpointSettings {
      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         return o == this ? true : o instanceof OAuth2MetadataSettings.JwksEndpointSettings;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int result = 1;
         return 1;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.JwksEndpointSettings()";
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2MetadataSettingsBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private Issuer issuer;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2IssuerValidationMode issuerValidationMode;
      @SuppressFBWarnings(justification = "generated code")
      private boolean authorizationCodeGrantSupported;
      @SuppressFBWarnings(justification = "generated code")
      private boolean clientCredentialsGrantSupported;
      @SuppressFBWarnings(justification = "generated code")
      private boolean tokenExchangeGrantSupported;
      @SuppressFBWarnings(justification = "generated code")
      private boolean generateRefreshToken;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.OpenIDConnectSettings openIDConnectSettings;
      @SuppressFBWarnings(justification = "generated code")
      private PkceCodeChallengeMethod pkceCodeChallengeMethod;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.RegistrationEndpointSettings registrationEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.JwksEndpointSettings jwksEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.AuthorizationEndpointSettings authorizationEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.TokenEndpointSettings tokenEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.PushedAuthorizationRequestEndpointSettings pushedAuthorizationRequestEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.TokenRevocationEndpointSettings tokenRevocationEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.TokenIntrospectionEndpointSettings tokenIntrospectionEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2MetadataSettings.UserInfoEndpointSettings userInfoEndpointSettings;
      @SuppressFBWarnings(justification = "generated code")
      private boolean checkSessionSupported;
      @SuppressFBWarnings(justification = "generated code")
      private ArrayList<UILocale> uiLocales;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2SupportedResponseModes supportedResponseModes;
      @SuppressFBWarnings(justification = "generated code")
      private boolean backChannelLogoutSupported;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder issuer(Issuer issuer) {
         this.issuer = issuer;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder issuerValidationMode(OAuth2IssuerValidationMode issuerValidationMode) {
         this.issuerValidationMode = issuerValidationMode;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder authorizationCodeGrantSupported(boolean authorizationCodeGrantSupported) {
         this.authorizationCodeGrantSupported = authorizationCodeGrantSupported;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder clientCredentialsGrantSupported(boolean clientCredentialsGrantSupported) {
         this.clientCredentialsGrantSupported = clientCredentialsGrantSupported;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder tokenExchangeGrantSupported(boolean tokenExchangeGrantSupported) {
         this.tokenExchangeGrantSupported = tokenExchangeGrantSupported;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder generateRefreshToken(boolean generateRefreshToken) {
         this.generateRefreshToken = generateRefreshToken;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder openIDConnectSettings(OAuth2MetadataSettings.OpenIDConnectSettings openIDConnectSettings) {
         this.openIDConnectSettings = openIDConnectSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder pkceCodeChallengeMethod(PkceCodeChallengeMethod pkceCodeChallengeMethod) {
         this.pkceCodeChallengeMethod = pkceCodeChallengeMethod;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder registrationEndpointSettings(
         OAuth2MetadataSettings.RegistrationEndpointSettings registrationEndpointSettings
      ) {
         this.registrationEndpointSettings = registrationEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder jwksEndpointSettings(OAuth2MetadataSettings.JwksEndpointSettings jwksEndpointSettings) {
         this.jwksEndpointSettings = jwksEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder authorizationEndpointSettings(
         OAuth2MetadataSettings.AuthorizationEndpointSettings authorizationEndpointSettings
      ) {
         this.authorizationEndpointSettings = authorizationEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder tokenEndpointSettings(OAuth2MetadataSettings.TokenEndpointSettings tokenEndpointSettings) {
         this.tokenEndpointSettings = tokenEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder pushedAuthorizationRequestEndpointSettings(
         OAuth2MetadataSettings.PushedAuthorizationRequestEndpointSettings pushedAuthorizationRequestEndpointSettings
      ) {
         this.pushedAuthorizationRequestEndpointSettings = pushedAuthorizationRequestEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder tokenRevocationEndpointSettings(
         OAuth2MetadataSettings.TokenRevocationEndpointSettings tokenRevocationEndpointSettings
      ) {
         this.tokenRevocationEndpointSettings = tokenRevocationEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder tokenIntrospectionEndpointSettings(
         OAuth2MetadataSettings.TokenIntrospectionEndpointSettings tokenIntrospectionEndpointSettings
      ) {
         this.tokenIntrospectionEndpointSettings = tokenIntrospectionEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder userInfoEndpointSettings(
         OAuth2MetadataSettings.UserInfoEndpointSettings userInfoEndpointSettings
      ) {
         this.userInfoEndpointSettings = userInfoEndpointSettings;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder checkSessionSupported(boolean checkSessionSupported) {
         this.checkSessionSupported = checkSessionSupported;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder uiLocale(UILocale uiLocale) {
         if (this.uiLocales == null) {
            this.uiLocales = new ArrayList<>();
         }

         this.uiLocales.add(uiLocale);
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder uiLocales(Collection<? extends UILocale> uiLocales) {
         if (uiLocales == null) {
            throw new NullPointerException("uiLocales cannot be null");
         }

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder clearUiLocales() {
         if (this.uiLocales != null) {
            this.uiLocales.clear();
         }

         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder supportedResponseModes(@NonNull OAuth2SupportedResponseModes supportedResponseModes) {
         if (supportedResponseModes == null) {
            throw new NullPointerException("supportedResponseModes is marked non-null but is null");
         }

         this.supportedResponseModes = supportedResponseModes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder backChannelLogoutSupported(boolean backChannelLogoutSupported) {
         this.backChannelLogoutSupported = backChannelLogoutSupported;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2MetadataSettings build() {
         return new OAuth2MetadataSettings(
            this.issuer,
            this.issuerValidationMode,
            this.authorizationCodeGrantSupported,
            this.clientCredentialsGrantSupported,
            this.tokenExchangeGrantSupported,
            this.generateRefreshToken,
            this.openIDConnectSettings,
            this.pkceCodeChallengeMethod,
            this.registrationEndpointSettings,
            this.jwksEndpointSettings,
            this.authorizationEndpointSettings,
            this.tokenEndpointSettings,
            this.pushedAuthorizationRequestEndpointSettings,
            this.tokenRevocationEndpointSettings,
            this.tokenIntrospectionEndpointSettings,
            this.userInfoEndpointSettings,
            this.checkSessionSupported,
            switch (this.uiLocales == null ? 0 : this.uiLocales.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.uiLocales.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.uiLocales));
            },
            this.supportedResponseModes,
            this.backChannelLogoutSupported
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.OAuth2MetadataSettingsBuilder(issuer="
            + this.issuer
            + ", issuerValidationMode="
            + this.issuerValidationMode
            + ", authorizationCodeGrantSupported="
            + this.authorizationCodeGrantSupported
            + ", clientCredentialsGrantSupported="
            + this.clientCredentialsGrantSupported
            + ", tokenExchangeGrantSupported="
            + this.tokenExchangeGrantSupported
            + ", generateRefreshToken="
            + this.generateRefreshToken
            + ", openIDConnectSettings="
            + this.openIDConnectSettings
            + ", pkceCodeChallengeMethod="
            + this.pkceCodeChallengeMethod
            + ", registrationEndpointSettings="
            + this.registrationEndpointSettings
            + ", jwksEndpointSettings="
            + this.jwksEndpointSettings
            + ", authorizationEndpointSettings="
            + this.authorizationEndpointSettings
            + ", tokenEndpointSettings="
            + this.tokenEndpointSettings
            + ", pushedAuthorizationRequestEndpointSettings="
            + this.pushedAuthorizationRequestEndpointSettings
            + ", tokenRevocationEndpointSettings="
            + this.tokenRevocationEndpointSettings
            + ", tokenIntrospectionEndpointSettings="
            + this.tokenIntrospectionEndpointSettings
            + ", userInfoEndpointSettings="
            + this.userInfoEndpointSettings
            + ", checkSessionSupported="
            + this.checkSessionSupported
            + ", uiLocales="
            + this.uiLocales
            + ", supportedResponseModes="
            + this.supportedResponseModes
            + ", backChannelLogoutSupported="
            + this.backChannelLogoutSupported
            + ")";
      }
   }

   public static final class OpenIDConnectSettings {
      private final List<OpenIdConnectAcrValue> acrValuesSupported;
      private final List<JWSAlgorithm> idTokenSigningAlgorithms;
      private final List<String> claimsSupported;
      private final List<ClaimType> claimTypesSupported;
      private final Set<OAuth2ResponseType> hybridFlowResponseTypesSupported;

      public OpenIDConnectSettings(
         List<OpenIdConnectAcrValue> acrValuesSupported,
         List<JWSAlgorithm> idTokenSigningAlgorithms,
         List<String> claimsSupported,
         List<ClaimType> claimTypesSupported,
         Set<OAuth2ResponseType> hybridFlowResponseTypesSupported
      ) {
         this.acrValuesSupported = Objects.requireNonNullElse(acrValuesSupported, List.of());
         this.idTokenSigningAlgorithms = Objects.requireNonNullElse(idTokenSigningAlgorithms, List.of(JWSAlgorithm.RS256));
         this.claimsSupported = Objects.requireNonNullElse(claimsSupported, List.of());
         this.claimTypesSupported = Objects.requireNonNullElse(claimTypesSupported, List.of(ClaimType.NORMAL));
         this.hybridFlowResponseTypesSupported = Objects.requireNonNull(hybridFlowResponseTypesSupported);
      }

      @SuppressFBWarnings(justification = "generated code")
      public static OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder builder() {
         return new OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder();
      }

      @SuppressFBWarnings(justification = "generated code")
      public List<OpenIdConnectAcrValue> acrValuesSupported() {
         return this.acrValuesSupported;
      }

      @SuppressFBWarnings(justification = "generated code")
      public List<JWSAlgorithm> idTokenSigningAlgorithms() {
         return this.idTokenSigningAlgorithms;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public List<ClaimType> claimTypesSupported() {
         return this.claimTypesSupported;
      }

      @SuppressFBWarnings(justification = "generated code")
      public Set<OAuth2ResponseType> hybridFlowResponseTypesSupported() {
         return this.hybridFlowResponseTypesSupported;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         if (o == this) {
            return true;
         } else if (!(o instanceof OAuth2MetadataSettings.OpenIDConnectSettings other)) {
            return false;
         } else {
            Object this$acrValuesSupported = this.acrValuesSupported;
            Object other$acrValuesSupported = other.acrValuesSupported;
            if (this$acrValuesSupported == null ? other$acrValuesSupported == null : this$acrValuesSupported.equals(other$acrValuesSupported)) {
               Object this$idTokenSigningAlgorithms = this.idTokenSigningAlgorithms;
               Object other$idTokenSigningAlgorithms = other.idTokenSigningAlgorithms;
               if (this$idTokenSigningAlgorithms == null
                  ? other$idTokenSigningAlgorithms == null
                  : this$idTokenSigningAlgorithms.equals(other$idTokenSigningAlgorithms)) {
                  Object this$claimsSupported = this.claimsSupported;
                  Object other$claimsSupported = other.claimsSupported;
                  if (this$claimsSupported == null ? other$claimsSupported == null : this$claimsSupported.equals(other$claimsSupported)) {
                     Object this$claimTypesSupported = this.claimTypesSupported;
                     Object other$claimTypesSupported = other.claimTypesSupported;
                     if (this$claimTypesSupported == null ? other$claimTypesSupported == null : this$claimTypesSupported.equals(other$claimTypesSupported)) {
                        Object this$hybridFlowResponseTypesSupported = this.hybridFlowResponseTypesSupported;
                        Object other$hybridFlowResponseTypesSupported = other.hybridFlowResponseTypesSupported;
                        return this$hybridFlowResponseTypesSupported == null
                           ? other$hybridFlowResponseTypesSupported == null
                           : this$hybridFlowResponseTypesSupported.equals(other$hybridFlowResponseTypesSupported);
                     } else {
                        return false;
                     }
                  } else {
                     return false;
                  }
               } else {
                  return false;
               }
            } else {
               return false;
            }
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int PRIME = 59;
         int result = 1;
         Object $acrValuesSupported = this.acrValuesSupported;
         result = result * 59 + ($acrValuesSupported == null ? 43 : $acrValuesSupported.hashCode());
         Object $idTokenSigningAlgorithms = this.idTokenSigningAlgorithms;
         result = result * 59 + ($idTokenSigningAlgorithms == null ? 43 : $idTokenSigningAlgorithms.hashCode());
         Object $claimsSupported = this.claimsSupported;
         result = result * 59 + ($claimsSupported == null ? 43 : $claimsSupported.hashCode());
         Object $claimTypesSupported = this.claimTypesSupported;
         result = result * 59 + ($claimTypesSupported == null ? 43 : $claimTypesSupported.hashCode());
         Object $hybridFlowResponseTypesSupported = this.hybridFlowResponseTypesSupported;
         return result * 59 + ($hybridFlowResponseTypesSupported == null ? 43 : $hybridFlowResponseTypesSupported.hashCode());
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.OpenIDConnectSettings(acrValuesSupported="
            + this.acrValuesSupported()
            + ", idTokenSigningAlgorithms="
            + this.idTokenSigningAlgorithms()
            + ", claimsSupported="
            + this.claimsSupported()
            + ", claimTypesSupported="
            + this.claimTypesSupported()
            + ", hybridFlowResponseTypesSupported="
            + this.hybridFlowResponseTypesSupported()
            + ")";
      }

      @SuppressFBWarnings(justification = "generated code")
      public static class OpenIDConnectSettingsBuilder {
         @SuppressFBWarnings(justification = "generated code")
         private ArrayList<OpenIdConnectAcrValue> acrValuesSupported;
         @SuppressFBWarnings(justification = "generated code")
         private ArrayList<JWSAlgorithm> idTokenSigningAlgorithms;
         @SuppressFBWarnings(justification = "generated code")
         private ArrayList<String> claimsSupported;
         @SuppressFBWarnings(justification = "generated code")
         private ArrayList<ClaimType> claimTypesSupported;
         @SuppressFBWarnings(justification = "generated code")
         private ArrayList<OAuth2ResponseType> hybridFlowResponseTypesSupported;

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

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder acrValueSupported(OpenIdConnectAcrValue acrValueSupported) {
            if (this.acrValuesSupported == null) {
               this.acrValuesSupported = new ArrayList<>();
            }

            this.acrValuesSupported.add(acrValueSupported);
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder acrValuesSupported(
            Collection<? extends OpenIdConnectAcrValue> acrValuesSupported
         ) {
            if (acrValuesSupported == null) {
               throw new NullPointerException("acrValuesSupported cannot be null");
            }

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

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

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder clearAcrValuesSupported() {
            if (this.acrValuesSupported != null) {
               this.acrValuesSupported.clear();
            }

            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder idTokenSigningAlgorithm(JWSAlgorithm idTokenSigningAlgorithm) {
            if (this.idTokenSigningAlgorithms == null) {
               this.idTokenSigningAlgorithms = new ArrayList<>();
            }

            this.idTokenSigningAlgorithms.add(idTokenSigningAlgorithm);
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder idTokenSigningAlgorithms(
            Collection<? extends JWSAlgorithm> idTokenSigningAlgorithms
         ) {
            if (idTokenSigningAlgorithms == null) {
               throw new NullPointerException("idTokenSigningAlgorithms cannot be null");
            }

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

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

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder clearIdTokenSigningAlgorithms() {
            if (this.idTokenSigningAlgorithms != null) {
               this.idTokenSigningAlgorithms.clear();
            }

            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder claimSupported(String claimSupported) {
            if (this.claimsSupported == null) {
               this.claimsSupported = new ArrayList<>();
            }

            this.claimsSupported.add(claimSupported);
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder claimsSupported(Collection<? extends String> claimsSupported) {
            if (claimsSupported == null) {
               throw new NullPointerException("claimsSupported cannot be null");
            }

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

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

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder clearClaimsSupported() {
            if (this.claimsSupported != null) {
               this.claimsSupported.clear();
            }

            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder claimTypeSupported(ClaimType claimTypeSupported) {
            if (this.claimTypesSupported == null) {
               this.claimTypesSupported = new ArrayList<>();
            }

            this.claimTypesSupported.add(claimTypeSupported);
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder claimTypesSupported(
            Collection<? extends ClaimType> claimTypesSupported
         ) {
            if (claimTypesSupported == null) {
               throw new NullPointerException("claimTypesSupported cannot be null");
            }

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

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

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder clearClaimTypesSupported() {
            if (this.claimTypesSupported != null) {
               this.claimTypesSupported.clear();
            }

            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder hybridFlowResponseTypesSupported(
            OAuth2ResponseType hybridFlowResponseTypesSupported
         ) {
            if (this.hybridFlowResponseTypesSupported == null) {
               this.hybridFlowResponseTypesSupported = new ArrayList<>();
            }

            this.hybridFlowResponseTypesSupported.add(hybridFlowResponseTypesSupported);
            return this;
         }

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder hybridFlowResponseTypesSupported(
            Collection<? extends OAuth2ResponseType> hybridFlowResponseTypesSupported
         ) {
            if (hybridFlowResponseTypesSupported == null) {
               throw new NullPointerException("hybridFlowResponseTypesSupported cannot be null");
            }

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

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

         @SuppressFBWarnings(justification = "generated code")
         public OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder clearHybridFlowResponseTypesSupported() {
            if (this.hybridFlowResponseTypesSupported != null) {
               this.hybridFlowResponseTypesSupported.clear();
            }

            return this;
         }

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

            List idTokenSigningAlgorithms = switch (this.idTokenSigningAlgorithms == null ? 0 : this.idTokenSigningAlgorithms.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.idTokenSigningAlgorithms.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.idTokenSigningAlgorithms));
            };

            List claimsSupported = switch (this.claimsSupported == null ? 0 : this.claimsSupported.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.claimsSupported.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.claimsSupported));
            };

            List claimTypesSupported = switch (this.claimTypesSupported == null ? 0 : this.claimTypesSupported.size()) {
               case 0 -> Collections.emptyList();
               case 1 -> Collections.singletonList(this.claimTypesSupported.get(0));
               default -> Collections.unmodifiableList(new ArrayList<>(this.claimTypesSupported));
            };

            return new OAuth2MetadataSettings.OpenIDConnectSettings(
               acrValuesSupported,
               idTokenSigningAlgorithms,
               claimsSupported,
               claimTypesSupported,
               switch (this.hybridFlowResponseTypesSupported == null ? 0 : this.hybridFlowResponseTypesSupported.size()) {
                  case 0 -> Collections.emptySet();
                  case 1 -> Collections.singleton(this.hybridFlowResponseTypesSupported.get(0));
                  default -> {
                     Set<OAuth2ResponseType> hybridFlowResponseTypesSupported = new LinkedHashSet<>(
                        this.hybridFlowResponseTypesSupported.size() < 1073741824
                           ? 1 + this.hybridFlowResponseTypesSupported.size() + (this.hybridFlowResponseTypesSupported.size() - 3) / 3
                           : Integer.MAX_VALUE
                     );
                     hybridFlowResponseTypesSupported.addAll(this.hybridFlowResponseTypesSupported);
                     yield Collections.unmodifiableSet(hybridFlowResponseTypesSupported);
                  }
               }
            );
         }

         @SuppressFBWarnings(justification = "generated code")
         @Override
         public String toString() {
            return "OAuth2MetadataSettings.OpenIDConnectSettings.OpenIDConnectSettingsBuilder(acrValuesSupported="
               + this.acrValuesSupported
               + ", idTokenSigningAlgorithms="
               + this.idTokenSigningAlgorithms
               + ", claimsSupported="
               + this.claimsSupported
               + ", claimTypesSupported="
               + this.claimTypesSupported
               + ", hybridFlowResponseTypesSupported="
               + this.hybridFlowResponseTypesSupported
               + ")";
         }
      }
   }

   public static final class PushedAuthorizationRequestEndpointSettings {
      private final boolean pushedAuthorizationRequestsRequired;

      @SuppressFBWarnings(justification = "generated code")
      public PushedAuthorizationRequestEndpointSettings(boolean pushedAuthorizationRequestsRequired) {
         this.pushedAuthorizationRequestsRequired = pushedAuthorizationRequestsRequired;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         if (o == this) {
            return true;
         } else {
            return !(o instanceof OAuth2MetadataSettings.PushedAuthorizationRequestEndpointSettings other)
               ? false
               : this.pushedAuthorizationRequestsRequired == other.pushedAuthorizationRequestsRequired;
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int PRIME = 59;
         int result = 1;
         return result * 59 + (this.pushedAuthorizationRequestsRequired ? 79 : 97);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.PushedAuthorizationRequestEndpointSettings(pushedAuthorizationRequestsRequired="
            + this.pushedAuthorizationRequestsRequired()
            + ")";
      }
   }

   public static final class RegistrationEndpointSettings {
      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         return o == this ? true : o instanceof OAuth2MetadataSettings.RegistrationEndpointSettings;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int result = 1;
         return 1;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.RegistrationEndpointSettings()";
      }
   }

   public static final class TokenEndpointSettings {
      private final List<ClientAuthenticationMethod> supportedAuthenticationMethods;

      @SuppressFBWarnings(justification = "generated code")
      public TokenEndpointSettings(List<ClientAuthenticationMethod> supportedAuthenticationMethods) {
         this.supportedAuthenticationMethods = supportedAuthenticationMethods;
      }

      @SuppressFBWarnings(justification = "generated code")
      public List<ClientAuthenticationMethod> supportedAuthenticationMethods() {
         return this.supportedAuthenticationMethods;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         if (o == this) {
            return true;
         } else if (!(o instanceof OAuth2MetadataSettings.TokenEndpointSettings other)) {
            return false;
         } else {
            Object this$supportedAuthenticationMethods = this.supportedAuthenticationMethods;
            Object other$supportedAuthenticationMethods = other.supportedAuthenticationMethods;
            return this$supportedAuthenticationMethods == null
               ? other$supportedAuthenticationMethods == null
               : this$supportedAuthenticationMethods.equals(other$supportedAuthenticationMethods);
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int PRIME = 59;
         int result = 1;
         Object $supportedAuthenticationMethods = this.supportedAuthenticationMethods;
         return result * 59 + ($supportedAuthenticationMethods == null ? 43 : $supportedAuthenticationMethods.hashCode());
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.TokenEndpointSettings(supportedAuthenticationMethods=" + this.supportedAuthenticationMethods() + ")";
      }
   }

   public static final class TokenIntrospectionEndpointSettings {
      private final ClientAuthenticationMethod authenticationMethod;

      @SuppressFBWarnings(justification = "generated code")
      public TokenIntrospectionEndpointSettings(ClientAuthenticationMethod authenticationMethod) {
         this.authenticationMethod = authenticationMethod;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ClientAuthenticationMethod authenticationMethod() {
         return this.authenticationMethod;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         if (o == this) {
            return true;
         } else if (!(o instanceof OAuth2MetadataSettings.TokenIntrospectionEndpointSettings other)) {
            return false;
         } else {
            Object this$authenticationMethod = this.authenticationMethod;
            Object other$authenticationMethod = other.authenticationMethod;
            return this$authenticationMethod == null ? other$authenticationMethod == null : this$authenticationMethod.equals(other$authenticationMethod);
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int PRIME = 59;
         int result = 1;
         Object $authenticationMethod = this.authenticationMethod;
         return result * 59 + ($authenticationMethod == null ? 43 : $authenticationMethod.hashCode());
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.TokenIntrospectionEndpointSettings(authenticationMethod=" + this.authenticationMethod() + ")";
      }
   }

   public static final class TokenRevocationEndpointSettings {
      private final ClientAuthenticationMethod authenticationMethod;

      @SuppressFBWarnings(justification = "generated code")
      public TokenRevocationEndpointSettings(ClientAuthenticationMethod authenticationMethod) {
         this.authenticationMethod = authenticationMethod;
      }

      @SuppressFBWarnings(justification = "generated code")
      public ClientAuthenticationMethod authenticationMethod() {
         return this.authenticationMethod;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         if (o == this) {
            return true;
         } else if (!(o instanceof OAuth2MetadataSettings.TokenRevocationEndpointSettings other)) {
            return false;
         } else {
            Object this$authenticationMethod = this.authenticationMethod;
            Object other$authenticationMethod = other.authenticationMethod;
            return this$authenticationMethod == null ? other$authenticationMethod == null : this$authenticationMethod.equals(other$authenticationMethod);
         }
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int PRIME = 59;
         int result = 1;
         Object $authenticationMethod = this.authenticationMethod;
         return result * 59 + ($authenticationMethod == null ? 43 : $authenticationMethod.hashCode());
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.TokenRevocationEndpointSettings(authenticationMethod=" + this.authenticationMethod() + ")";
      }
   }

   public static final class UserInfoEndpointSettings {
      @SuppressFBWarnings(justification = "generated code")
      @Override
      public boolean equals(Object o) {
         return o == this ? true : o instanceof OAuth2MetadataSettings.UserInfoEndpointSettings;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public int hashCode() {
         int result = 1;
         return 1;
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2MetadataSettings.UserInfoEndpointSettings()";
      }
   }
}
