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

import com.airlock.iam.common.api.application.configuration.claims.ClaimsValidatorConfig;
import com.airlock.iam.core.misc.util.httpclient.HttpClientConfig;
import com.airlock.iam.flow.api.application.configuration.redflag.RedFlagConfig;
import com.airlock.iam.oauth2.application.configuration.accountlinking.AccountLinkingSelfServiceConfig;
import com.airlock.iam.oauth2.application.configuration.accountregistration.AccountRegistrationConfig;
import com.airlock.iam.oauth2.application.configuration.client.AbstractOAuth2RemoteResourceConfig;
import com.airlock.iam.oauth2.application.configuration.client.OAuth2ClientResourceRequest;
import com.airlock.iam.oauth2.application.configuration.client.OAuth2PostLogoutRedirectUriConfig;
import com.airlock.iam.oauth2.application.configuration.client.OAuth2RedirectUriConfig;
import com.airlock.iam.oauth2.application.configuration.client.OAuth2RequestBuilderConfig;
import com.airlock.iam.oauth2.application.configuration.client.OAuth2SpaPostLogoutRedirectUriConfig;
import com.airlock.iam.oauth2.application.configuration.clientauthentication.OAuth2BasicAuthClientSecretConfig;
import com.airlock.iam.oauth2.application.configuration.logging.OAuth2LoggingSettings;
import com.airlock.iam.oauth2.domain.model.PkceCodeVerifierMethodClientConfig;
import com.airlock.iam.oauth2.domain.model.client.AudienceClaimValidationMethod;
import com.airlock.iam.oauth2.domain.model.client.communication.OAuth2TokenRequestClientSecretProcessor;
import com.airlock.iam.oauth2.domain.model.client.communication.OpenIDConnectIdTokenSignatureValidator;
import com.airlock.iam.plugin.api.annotation.config.ConfigurationValidator;
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.license.PluginLicenseRestriction;
import com.airlock.iam.plugin.api.annotation.property.EnumProperty;
import com.airlock.iam.plugin.api.annotation.property.GroupProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import com.airlock.iam.plugin.api.annotation.property.StringProperty;
import com.airlock.iam.plugin.api.config.ConfigurationContext;
import com.airlock.iam.plugin.api.config.ConfigurationEnvironment;
import com.airlock.iam.plugin.api.config.Environment;
import com.airlock.iam.plugin.api.config.PluginConfiguration;
import com.airlock.iam.plugin.api.exception.ConfigurationException;
import com.airlock.iam.plugin.api.exception.PropertyConstraintViolationException;
import com.airlock.iam.plugin.api.valuereader.PluginPropertyValueReader;
import com.airlock.iam.plugin.api.valuereader.StringPropertyValueReader;
import com.nimbusds.oauth2.sdk.util.StringUtils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.net.URI;
import java.util.List;
import java.util.Optional;

@Plugin(
   description = "OIDC Flow Client Settings. The settings define the OIDC handshake and can be referenced in flows through the provider id. When the OpenID Connect authorization was successful, the OAuth 2.0 Access Token and OpenID Connect ID Token is stored in the user session and can be used by the plugin OAuth 2.0 Tokens Map in the ID Propagation to provide the tokens to the backends.",
   displayName = "OIDC Flow Client"
)
@PluginLicenseRestriction(moduleAffiliation = "OAuthClient")
@Groups(
   groupSequence = {
         "Basic Settings",
         "Authorization Request",
         "Access Token Request",
         "ID Token",
         "Resource Mappings",
         "Authentication and Authorization",
         "Account Linking and Registration",
         "Logout",
         "Integration"
   },
   openGroups = {"Basic Settings", "Authorization Request", "Access Token Request", "Resource Mappings", "ID Token"}
)
public class OpenIDConnectSsoFlowClientSettings extends OpenIDConnectSsoFlowClientSettingsBase {
   public static final String OPENID_CLIENT_SETTINGS_DISPLAY_NAME = "OIDC Flow Client";
   @PluginProperty(description = "HTTP client used for token and pushed authorization endpoint requests.", displayName = "HTTP Client", optional = false)
   @GroupProperty(groupIdentifier = "Access Token Request")
   private HttpClientConfig httpClient;
   @PluginProperty(
      description = "Specifies how the client secret is included in requests to the token and pushed authorization request (PAR) endpoints.<p/><a target=\"_blank\" href=\"https://tools.ietf.org/html/rfc6749\">RFC 6749</a> suggests to use the HTTP Basic authentication scheme ('OAuth 2.0 Basic Auth Client Secret').",
      optional = true,
      defaultValue = OAuth2BasicAuthClientSecretConfig.class,
      displayName = "Token/PAR Endpoint Authentication"
   )
   @GroupProperty(groupIdentifier = "Access Token Request")
   private OAuth2TokenRequestClientSecretProcessor tokenEndpointAuthentication;
   @StringProperty(
      description = "Token endpoint URL to get Access and Refresh Tokens.",
      exampleValues = {
            "https://airlock.com/auth/rest/oauth2/authorization-servers/asId/token",
            "https://accounts.google.com/o/oauth2/token",
            "https://login.live.com/oauth20_token.srf"
      },
      optional = false
   )
   @GroupProperty(groupIdentifier = "Access Token Request")
   private String tokenEndpointURL;
   @StringProperty(
      description = "Authorization endpoint URL to obtain Authorization Codes from.",
      exampleValues = {
            "https://airlock.iam/auth/ui/app/auth/oauth2/authorization-servers/asId/authorize",
            "https://airlock.iam/auth/oauth2/v3/asId/authorize",
            "https://accounts.google.com/o/oauth2/auth",
            "https://login.live.com/oauth20_authorize.srf"
      },
      optional = false
   )
   @GroupProperty(groupIdentifier = "Authorization Request")
   private String authorizationEndpointURL;
   @StringProperty(
      description = "The pushed authorization request endpoint URI to send the Authorization Request to. If this property is set, the OpenID Connect client will send all Authorization Requests according to the PAR specification as defined in <a href=\"https://www.rfc-editor.org/rfc/rfc9126.html\" target=\"_blank\">RFC 9126</a>.",
      exampleValues = {"https://airlock.iam/auth/rest/oauth2/authorization-servers/asId/par", "https://as.example.org/as/par"},
      optional = true
   )
   @GroupProperty(groupIdentifier = "Authorization Request")
   private String pushedAuthorizationRequestEndpointURL;
   @EnumProperty(displayName = "PKCE Challenge Method", description = "Configures the PKCE challenge method.", optional = true, defaultValue = "S256")
   @GroupProperty(groupIdentifier = "Authorization Request")
   private PkceCodeVerifierMethodClientConfig pkceChallengeMethod;
   @PluginProperty(description = "ID token signature validation plugin.", optional = false)
   @GroupProperty(groupIdentifier = "ID Token")
   private OpenIDConnectIdTokenSignatureValidator signatureValidator;
   @StringProperty(
      description = "Defines the AS's logout endpoint URL. If configured, IAM notifies the AS that an end-user previously authenticated with this AS has logged out (RP-initiated logout).<br/>Note that the AS must support this feature.",
      displayName = "End Session Endpoint",
      optional = true
   )
   @GroupProperty(groupIdentifier = "Logout")
   private String endSessionEndpoint;
   private static final String END_SESSION_ENDPOINT_DISPLAY_NAME = "End Session Endpoint";
   private static final String END_SESSION_ENDPOINT_PROPERTY = "endSessionEndpoint";

   public OpenIDConnectSsoFlowClientSettings(
      String clientId,
      String clientSecret,
      OAuth2RequestBuilderConfig accessTokenRequestMethod,
      OAuth2LoggingSettings loggingSettings,
      boolean enableAccountLinking,
      String autoLinkExistingUsersContextDataField,
      AccountRegistrationConfig accountRegistrationConfig,
      OAuth2ProviderIdentifierConfig providerId,
      OAuth2RedirectUriConfig clientRedirectURI,
      List<OAuth2ClientResourceRequest> resourceRequests,
      AccountLinkingSelfServiceConfig accountLinkingSelfService,
      RedFlagConfig missingAccountLinkRedFlag,
      List<ClaimRequestConfig> claimsToRequest,
      List<String> acrValuesClaim,
      boolean includeNonce,
      boolean includeLanguageParameter,
      int maxAuthenticationAge,
      List<String> prompt,
      String customIssuerClaim,
      AudienceClaimValidationMethod audienceClaimValidationMethod,
      String customAudienceClaim,
      boolean enableAcrValidation,
      List<ClaimsValidatorConfig> additionalClaimValidators,
      List<String> scopesToRequest,
      List<AbstractOAuth2RemoteResourceConfig> idTokenResources,
      OAuth2PostLogoutRedirectUriConfig postLogoutRedirectUrl,
      HttpClientConfig httpClient,
      OAuth2TokenRequestClientSecretProcessor tokenEndpointAuthentication,
      String tokenEndpointURL,
      String authorizationEndpointURL,
      String pushedAuthorizationRequestEndpointURL,
      OpenIDConnectIdTokenSignatureValidator signatureValidator,
      String endSessionEndpoint,
      List<OpenIdConnectAuthorizationRequestParameterConfig> customAuthorizationRequestParameters,
      PkceCodeVerifierMethodClientConfig pkceChallengeMethod
   ) {
      super(
         clientId,
         clientSecret,
         accessTokenRequestMethod,
         loggingSettings,
         enableAccountLinking,
         autoLinkExistingUsersContextDataField,
         accountRegistrationConfig,
         providerId,
         clientRedirectURI,
         resourceRequests,
         accountLinkingSelfService,
         missingAccountLinkRedFlag,
         claimsToRequest,
         acrValuesClaim,
         includeNonce,
         includeLanguageParameter,
         maxAuthenticationAge,
         prompt,
         customIssuerClaim,
         audienceClaimValidationMethod,
         customAudienceClaim,
         enableAcrValidation,
         additionalClaimValidators,
         scopesToRequest,
         idTokenResources,
         postLogoutRedirectUrl,
         customAuthorizationRequestParameters
      );
      this.httpClient = httpClient;
      this.tokenEndpointAuthentication = tokenEndpointAuthentication;
      this.tokenEndpointURL = tokenEndpointURL;
      this.authorizationEndpointURL = authorizationEndpointURL;
      this.pushedAuthorizationRequestEndpointURL = pushedAuthorizationRequestEndpointURL;
      this.signatureValidator = signatureValidator;
      this.endSessionEndpoint = endSessionEndpoint;
      this.pkceChallengeMethod = pkceChallengeMethod;
   }

   @Override
   public boolean supportsEndSessionEndpoint() {
      return this.getEndSessionEndpoint() != null;
   }

   @Override
   public URI getEndSessionEndpoint() {
      return this.endSessionEndpoint != null ? URI.create(this.endSessionEndpoint) : null;
   }

   @ConfigurationValidator
   static void validateEndSessionEndpoint(
      PluginConfiguration config, ConfigurationEnvironment env, ConfigurationContext context, Environment validationEnvironment
   ) throws ConfigurationException {
      PluginConfiguration postLogoutRedirectUriPlugin = PluginPropertyValueReader.effectivePluginPropertyValue(config, "postLogoutRedirectUrl", env, context);
      if (postLogoutRedirectUriPlugin.isOfPluginClass(OAuth2SpaPostLogoutRedirectUriConfig.class)) {
         String endSessionEndpoint = StringPropertyValueReader.effectiveStringConfigValue(config, "endSessionEndpoint", env, context);
         if (StringUtils.isBlank(endSessionEndpoint)) {
            throw new PropertyConstraintViolationException(
               "postLogoutRedirectUrl",
               config,
               env,
               context,
               "Configuring a 'Post Logout Redirect URL' is only effective if also an 'End Session Endpoint' is configured"
            );
         }
      }
   }

   @Override
   public Optional<URI> getPushedAuthorizationRequestEndpointURL() {
      return Optional.ofNullable(this.pushedAuthorizationRequestEndpointURL).map(URI::create);
   }

   @Override
   public PkceCodeVerifierMethodClientConfig pkceChallengeMethod() {
      return this.pkceChallengeMethod;
   }

   @Override
   public HttpClientConfig getHttpClient() {
      return this.httpClient;
   }

   @Override
   public OAuth2TokenRequestClientSecretProcessor getTokenEndpointAuthentication() {
      return this.tokenEndpointAuthentication;
   }

   @Override
   public String getTokenEndpointURL() {
      return this.tokenEndpointURL;
   }

   @Override
   public String getAuthorizationEndpointURL() {
      return this.authorizationEndpointURL;
   }

   @Override
   public OpenIDConnectIdTokenSignatureValidator getSignatureValidator() {
      return this.signatureValidator;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OpenIDConnectSsoFlowClientSettingsBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String clientId;
      @SuppressFBWarnings(justification = "generated code")
      private String clientSecret;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2RequestBuilderConfig accessTokenRequestMethod;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2LoggingSettings loggingSettings;
      @SuppressFBWarnings(justification = "generated code")
      private boolean enableAccountLinking;
      @SuppressFBWarnings(justification = "generated code")
      private String autoLinkExistingUsersContextDataField;
      @SuppressFBWarnings(justification = "generated code")
      private AccountRegistrationConfig accountRegistrationConfig;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ProviderIdentifierConfig providerId;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2RedirectUriConfig clientRedirectURI;
      @SuppressFBWarnings(justification = "generated code")
      private List<OAuth2ClientResourceRequest> resourceRequests;
      @SuppressFBWarnings(justification = "generated code")
      private AccountLinkingSelfServiceConfig accountLinkingSelfService;
      @SuppressFBWarnings(justification = "generated code")
      private RedFlagConfig missingAccountLinkRedFlag;
      @SuppressFBWarnings(justification = "generated code")
      private List<ClaimRequestConfig> claimsToRequest;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> acrValuesClaim;
      @SuppressFBWarnings(justification = "generated code")
      private boolean includeNonce;
      @SuppressFBWarnings(justification = "generated code")
      private boolean includeLanguageParameter;
      @SuppressFBWarnings(justification = "generated code")
      private int maxAuthenticationAge;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> prompt;
      @SuppressFBWarnings(justification = "generated code")
      private String customIssuerClaim;
      @SuppressFBWarnings(justification = "generated code")
      private AudienceClaimValidationMethod audienceClaimValidationMethod;
      @SuppressFBWarnings(justification = "generated code")
      private String customAudienceClaim;
      @SuppressFBWarnings(justification = "generated code")
      private boolean enableAcrValidation;
      @SuppressFBWarnings(justification = "generated code")
      private List<ClaimsValidatorConfig> additionalClaimValidators;
      @SuppressFBWarnings(justification = "generated code")
      private List<String> scopesToRequest;
      @SuppressFBWarnings(justification = "generated code")
      private List<AbstractOAuth2RemoteResourceConfig> idTokenResources;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2PostLogoutRedirectUriConfig postLogoutRedirectUrl;
      @SuppressFBWarnings(justification = "generated code")
      private HttpClientConfig httpClient;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2TokenRequestClientSecretProcessor tokenEndpointAuthentication;
      @SuppressFBWarnings(justification = "generated code")
      private String tokenEndpointURL;
      @SuppressFBWarnings(justification = "generated code")
      private String authorizationEndpointURL;
      @SuppressFBWarnings(justification = "generated code")
      private String pushedAuthorizationRequestEndpointURL;
      @SuppressFBWarnings(justification = "generated code")
      private OpenIDConnectIdTokenSignatureValidator signatureValidator;
      @SuppressFBWarnings(justification = "generated code")
      private String endSessionEndpoint;
      @SuppressFBWarnings(justification = "generated code")
      private List<OpenIdConnectAuthorizationRequestParameterConfig> customAuthorizationRequestParameters;
      @SuppressFBWarnings(justification = "generated code")
      private PkceCodeVerifierMethodClientConfig pkceChallengeMethod;

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder clientId(String clientId) {
         this.clientId = clientId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder clientSecret(String clientSecret) {
         this.clientSecret = clientSecret;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder accessTokenRequestMethod(
         OAuth2RequestBuilderConfig accessTokenRequestMethod
      ) {
         this.accessTokenRequestMethod = accessTokenRequestMethod;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder loggingSettings(OAuth2LoggingSettings loggingSettings) {
         this.loggingSettings = loggingSettings;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder autoLinkExistingUsersContextDataField(
         String autoLinkExistingUsersContextDataField
      ) {
         this.autoLinkExistingUsersContextDataField = autoLinkExistingUsersContextDataField;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder accountRegistrationConfig(
         AccountRegistrationConfig accountRegistrationConfig
      ) {
         this.accountRegistrationConfig = accountRegistrationConfig;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder providerId(OAuth2ProviderIdentifierConfig providerId) {
         this.providerId = providerId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder clientRedirectURI(OAuth2RedirectUriConfig clientRedirectURI) {
         this.clientRedirectURI = clientRedirectURI;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder resourceRequests(List<OAuth2ClientResourceRequest> resourceRequests) {
         this.resourceRequests = resourceRequests;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder accountLinkingSelfService(
         AccountLinkingSelfServiceConfig accountLinkingSelfService
      ) {
         this.accountLinkingSelfService = accountLinkingSelfService;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder missingAccountLinkRedFlag(RedFlagConfig missingAccountLinkRedFlag) {
         this.missingAccountLinkRedFlag = missingAccountLinkRedFlag;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder claimsToRequest(List<ClaimRequestConfig> claimsToRequest) {
         this.claimsToRequest = claimsToRequest;
         return this;
      }

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

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

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder maxAuthenticationAge(int maxAuthenticationAge) {
         this.maxAuthenticationAge = maxAuthenticationAge;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder customIssuerClaim(String customIssuerClaim) {
         this.customIssuerClaim = customIssuerClaim;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder audienceClaimValidationMethod(
         AudienceClaimValidationMethod audienceClaimValidationMethod
      ) {
         this.audienceClaimValidationMethod = audienceClaimValidationMethod;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder customAudienceClaim(String customAudienceClaim) {
         this.customAudienceClaim = customAudienceClaim;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder additionalClaimValidators(
         List<ClaimsValidatorConfig> additionalClaimValidators
      ) {
         this.additionalClaimValidators = additionalClaimValidators;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder idTokenResources(
         List<AbstractOAuth2RemoteResourceConfig> idTokenResources
      ) {
         this.idTokenResources = idTokenResources;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder postLogoutRedirectUrl(
         OAuth2PostLogoutRedirectUriConfig postLogoutRedirectUrl
      ) {
         this.postLogoutRedirectUrl = postLogoutRedirectUrl;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder httpClient(HttpClientConfig httpClient) {
         this.httpClient = httpClient;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder tokenEndpointAuthentication(
         OAuth2TokenRequestClientSecretProcessor tokenEndpointAuthentication
      ) {
         this.tokenEndpointAuthentication = tokenEndpointAuthentication;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder tokenEndpointURL(String tokenEndpointURL) {
         this.tokenEndpointURL = tokenEndpointURL;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder authorizationEndpointURL(String authorizationEndpointURL) {
         this.authorizationEndpointURL = authorizationEndpointURL;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder pushedAuthorizationRequestEndpointURL(
         String pushedAuthorizationRequestEndpointURL
      ) {
         this.pushedAuthorizationRequestEndpointURL = pushedAuthorizationRequestEndpointURL;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder signatureValidator(
         OpenIDConnectIdTokenSignatureValidator signatureValidator
      ) {
         this.signatureValidator = signatureValidator;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder endSessionEndpoint(String endSessionEndpoint) {
         this.endSessionEndpoint = endSessionEndpoint;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder customAuthorizationRequestParameters(
         List<OpenIdConnectAuthorizationRequestParameterConfig> customAuthorizationRequestParameters
      ) {
         this.customAuthorizationRequestParameters = customAuthorizationRequestParameters;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder pkceChallengeMethod(
         PkceCodeVerifierMethodClientConfig pkceChallengeMethod
      ) {
         this.pkceChallengeMethod = pkceChallengeMethod;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIDConnectSsoFlowClientSettings build() {
         return new OpenIDConnectSsoFlowClientSettings(
            this.clientId,
            this.clientSecret,
            this.accessTokenRequestMethod,
            this.loggingSettings,
            this.enableAccountLinking,
            this.autoLinkExistingUsersContextDataField,
            this.accountRegistrationConfig,
            this.providerId,
            this.clientRedirectURI,
            this.resourceRequests,
            this.accountLinkingSelfService,
            this.missingAccountLinkRedFlag,
            this.claimsToRequest,
            this.acrValuesClaim,
            this.includeNonce,
            this.includeLanguageParameter,
            this.maxAuthenticationAge,
            this.prompt,
            this.customIssuerClaim,
            this.audienceClaimValidationMethod,
            this.customAudienceClaim,
            this.enableAcrValidation,
            this.additionalClaimValidators,
            this.scopesToRequest,
            this.idTokenResources,
            this.postLogoutRedirectUrl,
            this.httpClient,
            this.tokenEndpointAuthentication,
            this.tokenEndpointURL,
            this.authorizationEndpointURL,
            this.pushedAuthorizationRequestEndpointURL,
            this.signatureValidator,
            this.endSessionEndpoint,
            this.customAuthorizationRequestParameters,
            this.pkceChallengeMethod
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OpenIDConnectSsoFlowClientSettings.OpenIDConnectSsoFlowClientSettingsBuilder(clientId="
            + this.clientId
            + ", clientSecret="
            + this.clientSecret
            + ", accessTokenRequestMethod="
            + this.accessTokenRequestMethod
            + ", loggingSettings="
            + this.loggingSettings
            + ", enableAccountLinking="
            + this.enableAccountLinking
            + ", autoLinkExistingUsersContextDataField="
            + this.autoLinkExistingUsersContextDataField
            + ", accountRegistrationConfig="
            + this.accountRegistrationConfig
            + ", providerId="
            + this.providerId
            + ", clientRedirectURI="
            + this.clientRedirectURI
            + ", resourceRequests="
            + this.resourceRequests
            + ", accountLinkingSelfService="
            + this.accountLinkingSelfService
            + ", missingAccountLinkRedFlag="
            + this.missingAccountLinkRedFlag
            + ", claimsToRequest="
            + this.claimsToRequest
            + ", acrValuesClaim="
            + this.acrValuesClaim
            + ", includeNonce="
            + this.includeNonce
            + ", includeLanguageParameter="
            + this.includeLanguageParameter
            + ", maxAuthenticationAge="
            + this.maxAuthenticationAge
            + ", prompt="
            + this.prompt
            + ", customIssuerClaim="
            + this.customIssuerClaim
            + ", audienceClaimValidationMethod="
            + this.audienceClaimValidationMethod
            + ", customAudienceClaim="
            + this.customAudienceClaim
            + ", enableAcrValidation="
            + this.enableAcrValidation
            + ", additionalClaimValidators="
            + this.additionalClaimValidators
            + ", scopesToRequest="
            + this.scopesToRequest
            + ", idTokenResources="
            + this.idTokenResources
            + ", postLogoutRedirectUrl="
            + this.postLogoutRedirectUrl
            + ", httpClient="
            + this.httpClient
            + ", tokenEndpointAuthentication="
            + this.tokenEndpointAuthentication
            + ", tokenEndpointURL="
            + this.tokenEndpointURL
            + ", authorizationEndpointURL="
            + this.authorizationEndpointURL
            + ", pushedAuthorizationRequestEndpointURL="
            + this.pushedAuthorizationRequestEndpointURL
            + ", signatureValidator="
            + this.signatureValidator
            + ", endSessionEndpoint="
            + this.endSessionEndpoint
            + ", customAuthorizationRequestParameters="
            + this.customAuthorizationRequestParameters
            + ", pkceChallengeMethod="
            + this.pkceChallengeMethod
            + ")";
      }
   }
}
