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

import com.airlock.iam.oauth2.api.domain.model.OAuth2ClientId;
import com.airlock.iam.oauth2.api.domain.model.OAuth2Scope;
import com.airlock.iam.oauth2.domain.model.OAuth2ResponseMode;
import com.airlock.iam.oauth2.domain.model.State;
import com.airlock.iam.oauth2.domain.model.acr.OpenIdConnectAcrValue;
import com.airlock.iam.oauth2.domain.model.authentication.OpenIdConnectLoginHint;
import com.airlock.iam.oauth2.domain.model.authorization.OAuth2ResponseType;
import com.airlock.iam.oauth2.domain.model.session.PkceCodeChallenge;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.net.URI;
import java.time.Duration;
import java.util.List;
import java.util.Optional;
import lombok.NonNull;

public record OpenIdConnectAuthenticationRequestAttributes(
   @NonNull OAuth2ClientId clientId,
   @NonNull Optional<URI> requestedRedirectUri,
   @NonNull URI effectiveRedirectUri,
   @NonNull Optional<State> state,
   @NonNull Optional<PkceCodeChallenge> pkceChallenge,
   @NonNull OAuth2ResponseType responseType,
   @NonNull List<OAuth2Scope> requestedScopes,
   @NonNull OAuth2ResponseMode responseMode,
   @NonNull List<OpenIdConnectAcrValue> acrValues,
   @NonNull Optional<String> nonce,
   @NonNull List<PromptValue> prompt,
   @NonNull Optional<OpenIdConnectLoginHint> loginHint,
   @NonNull Optional<Duration> maxAge
) implements OAuth2OidcAuthorizationRequestAttributes {
   @SuppressFBWarnings(justification = "generated code")
   public OpenIdConnectAuthenticationRequestAttributes {
      if (clientId == null) {
         throw new NullPointerException("clientId is marked non-null but is null");
      }

      if (requestedRedirectUri == null) {
         throw new NullPointerException("requestedRedirectUri is marked non-null but is null");
      }

      if (effectiveRedirectUri == null) {
         throw new NullPointerException("effectiveRedirectUri is marked non-null but is null");
      }

      if (state == null) {
         throw new NullPointerException("state is marked non-null but is null");
      }

      if (pkceChallenge == null) {
         throw new NullPointerException("pkceChallenge is marked non-null but is null");
      }

      if (responseType == null) {
         throw new NullPointerException("responseType is marked non-null but is null");
      }

      if (requestedScopes == null) {
         throw new NullPointerException("requestedScopes is marked non-null but is null");
      }

      if (responseMode == null) {
         throw new NullPointerException("responseMode is marked non-null but is null");
      }

      if (acrValues == null) {
         throw new NullPointerException("acrValues is marked non-null but is null");
      }

      if (nonce == null) {
         throw new NullPointerException("nonce is marked non-null but is null");
      }

      if (prompt == null) {
         throw new NullPointerException("prompt is marked non-null but is null");
      }

      if (loginHint == null) {
         throw new NullPointerException("loginHint is marked non-null but is null");
      }

      if (maxAge == null) {
         throw new NullPointerException("maxAge is marked non-null but is null");
      }
   }

   public OpenIdConnectAuthenticationRequestAttributes(
      @NonNull OAuth2AuthorizationRequestAttributes oauth2Attributes,
      @NonNull List<OpenIdConnectAcrValue> acrValues,
      @NonNull Optional<String> nonce,
      @NonNull List<PromptValue> prompt,
      @NonNull Optional<OpenIdConnectLoginHint> loginHint,
      @NonNull Optional<Duration> maxAge
   ) {
      this(
         oauth2Attributes.clientId(),
         oauth2Attributes.requestedRedirectUri(),
         oauth2Attributes.effectiveRedirectUri(),
         oauth2Attributes.state(),
         oauth2Attributes.pkceChallenge(),
         oauth2Attributes.responseType(),
         oauth2Attributes.requestedScopes(),
         oauth2Attributes.responseMode(),
         acrValues,
         nonce,
         prompt,
         loginHint,
         maxAge
      );
      if (oauth2Attributes == null) {
         throw new NullPointerException("oauth2Attributes is marked non-null but is null");
      }

      if (acrValues == null) {
         throw new NullPointerException("acrValues is marked non-null but is null");
      }

      if (nonce == null) {
         throw new NullPointerException("nonce is marked non-null but is null");
      }

      if (prompt == null) {
         throw new NullPointerException("prompt is marked non-null but is null");
      }

      if (loginHint == null) {
         throw new NullPointerException("loginHint is marked non-null but is null");
      }

      if (maxAge == null) {
         throw new NullPointerException("maxAge is marked non-null but is null");
      }
   }

   @Override
   public boolean isOpenIdConnect() {
      return true;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OpenIdConnectAuthenticationRequestAttributesBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ClientId clientId;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<URI> requestedRedirectUri;
      @SuppressFBWarnings(justification = "generated code")
      private URI effectiveRedirectUri;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<State> state;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<PkceCodeChallenge> pkceChallenge;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ResponseType responseType;
      @SuppressFBWarnings(justification = "generated code")
      private List<OAuth2Scope> requestedScopes;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2ResponseMode responseMode;
      @SuppressFBWarnings(justification = "generated code")
      private List<OpenIdConnectAcrValue> acrValues;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<String> nonce;
      @SuppressFBWarnings(justification = "generated code")
      private List<PromptValue> prompt;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<OpenIdConnectLoginHint> loginHint;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<Duration> maxAge;

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder clientId(@NonNull OAuth2ClientId clientId) {
         if (clientId == null) {
            throw new NullPointerException("clientId is marked non-null but is null");
         }

         this.clientId = clientId;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder requestedRedirectUri(
         @NonNull Optional<URI> requestedRedirectUri
      ) {
         if (requestedRedirectUri == null) {
            throw new NullPointerException("requestedRedirectUri is marked non-null but is null");
         }

         this.requestedRedirectUri = requestedRedirectUri;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder effectiveRedirectUri(
         @NonNull URI effectiveRedirectUri
      ) {
         if (effectiveRedirectUri == null) {
            throw new NullPointerException("effectiveRedirectUri is marked non-null but is null");
         }

         this.effectiveRedirectUri = effectiveRedirectUri;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder state(@NonNull Optional<State> state) {
         if (state == null) {
            throw new NullPointerException("state is marked non-null but is null");
         }

         this.state = state;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder pkceChallenge(
         @NonNull Optional<PkceCodeChallenge> pkceChallenge
      ) {
         if (pkceChallenge == null) {
            throw new NullPointerException("pkceChallenge is marked non-null but is null");
         }

         this.pkceChallenge = pkceChallenge;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder responseType(
         @NonNull OAuth2ResponseType responseType
      ) {
         if (responseType == null) {
            throw new NullPointerException("responseType is marked non-null but is null");
         }

         this.responseType = responseType;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder requestedScopes(
         @NonNull List<OAuth2Scope> requestedScopes
      ) {
         if (requestedScopes == null) {
            throw new NullPointerException("requestedScopes is marked non-null but is null");
         }

         this.requestedScopes = requestedScopes;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder responseMode(
         @NonNull OAuth2ResponseMode responseMode
      ) {
         if (responseMode == null) {
            throw new NullPointerException("responseMode is marked non-null but is null");
         }

         this.responseMode = responseMode;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder acrValues(
         @NonNull List<OpenIdConnectAcrValue> acrValues
      ) {
         if (acrValues == null) {
            throw new NullPointerException("acrValues is marked non-null but is null");
         }

         this.acrValues = acrValues;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder nonce(@NonNull Optional<String> nonce) {
         if (nonce == null) {
            throw new NullPointerException("nonce is marked non-null but is null");
         }

         this.nonce = nonce;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder prompt(@NonNull List<PromptValue> prompt) {
         if (prompt == null) {
            throw new NullPointerException("prompt is marked non-null but is null");
         }

         this.prompt = prompt;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder loginHint(
         @NonNull Optional<OpenIdConnectLoginHint> loginHint
      ) {
         if (loginHint == null) {
            throw new NullPointerException("loginHint is marked non-null but is null");
         }

         this.loginHint = loginHint;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder maxAge(@NonNull Optional<Duration> maxAge) {
         if (maxAge == null) {
            throw new NullPointerException("maxAge is marked non-null but is null");
         }

         this.maxAge = maxAge;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectAuthenticationRequestAttributes build() {
         return new OpenIdConnectAuthenticationRequestAttributes(
            this.clientId,
            this.requestedRedirectUri,
            this.effectiveRedirectUri,
            this.state,
            this.pkceChallenge,
            this.responseType,
            this.requestedScopes,
            this.responseMode,
            this.acrValues,
            this.nonce,
            this.prompt,
            this.loginHint,
            this.maxAge
         );
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OpenIdConnectAuthenticationRequestAttributes.OpenIdConnectAuthenticationRequestAttributesBuilder(clientId="
            + this.clientId
            + ", requestedRedirectUri="
            + this.requestedRedirectUri
            + ", effectiveRedirectUri="
            + this.effectiveRedirectUri
            + ", state="
            + this.state
            + ", pkceChallenge="
            + this.pkceChallenge
            + ", responseType="
            + this.responseType
            + ", requestedScopes="
            + this.requestedScopes
            + ", responseMode="
            + this.responseMode
            + ", acrValues="
            + this.acrValues
            + ", nonce="
            + this.nonce
            + ", prompt="
            + this.prompt
            + ", loginHint="
            + this.loginHint
            + ", maxAge="
            + this.maxAge
            + ")";
      }
   }
}
