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

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.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.IntegerProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.Duration;

@Plugin(
   description = "<p>Configures <a href=\"https://datatracker.ietf.org/doc/html/rfc9126\" target=\"_blank\">OAuth 2.0 Pushed Authorization Requests (PAR)</a>.</p>\n<p>The endpoint is located at <tt>/&lt;loginapp-uri&gt;/rest/oauth2/authorization-servers/<i>&lt;as-identifier&gt;</i>/par</tt>.\nClients must authenticate to call this endpoint. The PAR endpoint uses the same authentication method as configured for the token endpoint.</p>\n<p>To prevent attacks like swapping an obtained request_uri, clients should make use of PKCE, use a unique state parameter, or use the OIDC \"nonce\" parameter.\n</p>\n",
   displayName = "OAuth 2.0 Pushed Authorization Requests"
)
@PluginLicenseRestriction(moduleAffiliation = "OAuthServer")
public class OAuth2ParConfig {
   @IntegerProperty(
      description = "<p>The lifetime of the generated PAR request URI in seconds.<p>\n<p>A general guidance for the validity time would be less than a minute.</p>\n",
      displayName = "Request URI Lifetime [s]",
      optional = true,
      defaultValue = 30,
      exampleValues = {5, 60},
      minValue = 1
   )
   private int requestUriLifetime;
   @PluginProperty(
      displayName = "OAuth 2.0 PAR Repository",
      description = "OAuth 2.0 PAR repository configuration to store pushed authorization requests in the database.",
      optional = false
   )
   private OAuth2ParRequestRepositoryConfig repository;
   @BooleanProperty(
      displayName = "Require PAR",
      description = "If this flag is set, all authorization requests made to the authorization server must use PAR.\nNon-PAR requests will lead to an <tt>invalid_request</tt> error.\n",
      optional = true,
      defaultValue = "false"
   )
   private boolean requirePar;

   public Duration getRequestUriLifetime() {
      return Duration.ofSeconds(this.requestUriLifetime);
   }

   public OAuth2ParRequestRepositoryConfig getRepository() {
      return this.repository;
   }

   public boolean isParRequired() {
      return this.requirePar;
   }

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

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

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2ParConfig(int requestUriLifetime, OAuth2ParRequestRepositoryConfig repository, boolean requirePar) {
      this.requestUriLifetime = requestUriLifetime;
      this.repository = repository;
      this.requirePar = requirePar;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2ParConfigBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private int requestUriLifetime;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ParRequestRepositoryConfig repository;
      @SuppressFBWarnings(justification = "generated code")
      private boolean requirePar;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ParConfig.OAuth2ParConfigBuilder requestUriLifetime(int requestUriLifetime) {
         this.requestUriLifetime = requestUriLifetime;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ParConfig.OAuth2ParConfigBuilder repository(OAuth2ParRequestRepositoryConfig repository) {
         this.repository = repository;
         return this;
      }

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2ParConfig build() {
         return new OAuth2ParConfig(this.requestUriLifetime, this.repository, this.requirePar);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2ParConfig.OAuth2ParConfigBuilder(requestUriLifetime="
            + this.requestUriLifetime
            + ", repository="
            + this.repository
            + ", requirePar="
            + this.requirePar
            + ")";
      }
   }
}
