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

import com.airlock.iam.oauth2.domain.model.validation.OAuth2Error;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;
import java.util.regex.Pattern;

public final class OAuth2TokenExchangeErrorResponse {
   private static final Pattern ERROR_RESPONSE_INVALID_CHARACTERS_PATTERN = Pattern.compile("[^\\x20-\\x21\\x23-\\x5B\\x5D-\\x7E]");
   private final OAuth2Error errorCode;
   private final Optional<String> description;
   private final Optional<Integer> statusCode;

   public static OAuth2TokenExchangeErrorResponse tokenExchangeErrorResponse(OAuth2Error error) {
      return new OAuth2TokenExchangeErrorResponse(error, Optional.empty(), Optional.empty());
   }

   public static OAuth2TokenExchangeErrorResponse tokenExchangeErrorResponse(OAuth2Error error, String description) {
      return new OAuth2TokenExchangeErrorResponse(error, Optional.of(sanitizeDescription(description)), Optional.empty());
   }

   private static String sanitizeDescription(String description) {
      return ERROR_RESPONSE_INVALID_CHARACTERS_PATTERN.matcher(description).replaceAll("?");
   }

   public static OAuth2TokenExchangeErrorResponse tokenExchangeErrorResponse(OAuth2Error error, int statusCode) {
      return new OAuth2TokenExchangeErrorResponse(error, Optional.empty(), Optional.of(statusCode));
   }

   public static OAuth2TokenExchangeErrorResponse tokenExchangeErrorResponse(OAuth2Error error, String description, int statusCode) {
      return new OAuth2TokenExchangeErrorResponse(error, Optional.of(sanitizeDescription(description)), Optional.of(statusCode));
   }

   @SuppressFBWarnings(justification = "generated code")
   private OAuth2TokenExchangeErrorResponse(OAuth2Error errorCode, Optional<String> description, Optional<Integer> statusCode) {
      this.errorCode = errorCode;
      this.description = description;
      this.statusCode = statusCode;
   }

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2Error getErrorCode() {
      return this.errorCode;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public Optional<Integer> getStatusCode() {
      return this.statusCode;
   }
}
