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

import com.airlock.iam.common.domain.model.jwt.signature.JsonWebSignatureToken;
import com.airlock.iam.oauth2.api.domain.model.clientauthentication.OAuth2AuthClientId;
import com.airlock.iam.oauth2.api.domain.model.clientauthentication.OAuth2ClientAuthenticationPayload;
import com.airlock.iam.oauth2.api.domain.model.clientauthentication.OAuth2ClientAuthenticationVerificationMethod;
import com.airlock.iam.oauth2.domain.model.clientauthentication.method.KnownClientAuthenticationMethod;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.text.ParseException;
import java.util.Optional;

public record OpenIdConnectPrivateKeyJwtAuthenticationPayload(String assertionType, String assertion, Optional<String> clientIdFromRequest)
   implements OAuth2ClientAuthenticationPayload {
   @Override
   public Optional<OAuth2AuthClientId> clientId() {
      return this.parsedAssertion().flatMap(jwt -> jwt.claimsSet().issuer()).map(OAuth2AuthClientId::oAuth2AuthClientId);
   }

   private Optional<JsonWebSignatureToken> parsedAssertion() {
      try {
         return Optional.of(new JsonWebSignatureToken(this.assertion));
      } catch (ParseException e) {
         return Optional.empty();
      }
   }

   @Override
   public OAuth2ClientAuthenticationVerificationMethod method() {
      return KnownClientAuthenticationMethod.PRIVATE_KEY_JWT;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public static class OpenIdConnectPrivateKeyJwtAuthenticationPayloadBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private String assertionType;
      @SuppressFBWarnings(justification = "generated code")
      private String assertion;
      @SuppressFBWarnings(justification = "generated code")
      private Optional<String> clientIdFromRequest;

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

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectPrivateKeyJwtAuthenticationPayload.OpenIdConnectPrivateKeyJwtAuthenticationPayloadBuilder assertionType(String assertionType) {
         this.assertionType = assertionType;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectPrivateKeyJwtAuthenticationPayload.OpenIdConnectPrivateKeyJwtAuthenticationPayloadBuilder assertion(String assertion) {
         this.assertion = assertion;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectPrivateKeyJwtAuthenticationPayload.OpenIdConnectPrivateKeyJwtAuthenticationPayloadBuilder clientIdFromRequest(
         Optional<String> clientIdFromRequest
      ) {
         this.clientIdFromRequest = clientIdFromRequest;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OpenIdConnectPrivateKeyJwtAuthenticationPayload build() {
         return new OpenIdConnectPrivateKeyJwtAuthenticationPayload(this.assertionType, this.assertion, this.clientIdFromRequest);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OpenIdConnectPrivateKeyJwtAuthenticationPayload.OpenIdConnectPrivateKeyJwtAuthenticationPayloadBuilder(assertionType="
            + this.assertionType
            + ", assertion="
            + this.assertion
            + ", clientIdFromRequest="
            + this.clientIdFromRequest
            + ")";
      }
   }
}
