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

import com.airlock.iam.common.domain.model.jwt.JwtClaimsSet;
import com.airlock.iam.common.domain.model.jwt.signature.JsonWebSignatureToken;
import com.airlock.iam.oauth2.api.domain.model.tokenexchange.OAuth2TokenExchangeRawToken;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.Instant;
import java.util.Map;
import java.util.Optional;

public final class OAuth2TokenExchangeSignedJwtToken {
   private final JsonWebSignatureToken value;
   private final JwtClaimsSet claimSet;

   public static Optional<OAuth2TokenExchangeSignedJwtToken> parse(OAuth2TokenExchangeRawToken rawToken) {
      return JsonWebSignatureToken.parse(rawToken.getValue())
         .flatMap(jwt -> Optional.of(jwt.claimsSet()))
         .map(claimSet -> new OAuth2TokenExchangeSignedJwtToken(JsonWebSignatureToken.of(rawToken.getValue()), claimSet));
   }

   public Optional<OAuth2TokenExchangeTokenIssuerId> getIssuerId() {
      return this.claimSet.issuer().map(OAuth2TokenExchangeTokenIssuerId::tokenIssuerId);
   }

   public boolean isValidAt(Instant instant) {
      return this.getNotBeforeTime().map(instant::isAfter).orElse(true) && this.getExpirationTime().map(instant::isBefore).orElse(true);
   }

   public Map<String, Object> getAllClaims() {
      return this.claimSet.claims();
   }

   private Optional<Instant> getNotBeforeTime() {
      return this.claimSet.notBeforeTime();
   }

   private Optional<Instant> getExpirationTime() {
      return this.claimSet.expirationTime();
   }

   @SuppressFBWarnings(justification = "generated code")
   private OAuth2TokenExchangeSignedJwtToken(JsonWebSignatureToken value, JwtClaimsSet claimSet) {
      this.value = value;
      this.claimSet = claimSet;
   }

   @SuppressFBWarnings(justification = "generated code")
   public JsonWebSignatureToken getValue() {
      return this.value;
   }
}
