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

import com.airlock.iam.oauth2.api.domain.model.OAuth2ClientId;
import com.airlock.iam.oauth2.domain.model.token.OAuth2RawAccessTokenContainer;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

public final class OAuth2TokenLogMessageGenerator {
   static final String TOKEN_LOG_STRING_OLD_REFRESH_TOKEN = "old Refresh Token=";
   static final String TOKEN_LOG_STRING_NEW_REFRESH_TOKEN = "new Refresh Token=";
   static final String TOKEN_LOG_STRING_NEW_ACCESS_TOKEN = "new Access Token=";
   private static final String TOKEN_LOG_STRING_START = "Token information: ";
   private final OAuth2TokenRepresentation representation;

   public String getRefreshTokenLogMessage(
      String message, OAuth2ClientId clientId, String oldRefreshTokenString, Optional<OAuth2RawAccessTokenContainer> newTokens
   ) {
      StringBuilder sb = new StringBuilder(message + " Client ID: '" + clientId + "'");
      sb.append(", ").append("Token information: ");
      sb.append(this.getLogStringForToken("old Refresh Token=", oldRefreshTokenString));
      if (newTokens.isPresent()) {
         sb.append(this.getLogStringForNewTokens(newTokens.get()));
      } else {
         sb.append(", no new Refresh Token, no new Access Token");
      }

      return sb.toString();
   }

   private String getLogStringForNewTokens(OAuth2RawAccessTokenContainer newTokens) {
      Optional<String> rawRefreshTokenOpt = newTokens.getRawRefreshTokenString();
      StringBuilder sb = new StringBuilder();
      if (rawRefreshTokenOpt.isPresent()) {
         sb.append(this.getCompleteLogStringForToken("new Refresh Token=", rawRefreshTokenOpt.get()));
      } else {
         sb.append(", no new Refresh Token");
      }

      sb.append(this.getCompleteLogStringForToken("new Access Token=", newTokens.getRawAccessTokenString()));
      return sb.toString();
   }

   private String getCompleteLogStringForToken(String tokenStringTypeMsg, String tokenString) {
      return ", " + this.getLogStringForToken(tokenStringTypeMsg, tokenString);
   }

   private String getLogStringForToken(String introString, String tokenString) {
      return introString + "'" + this.representation.apply(tokenString) + "'";
   }

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2TokenLogMessageGenerator(OAuth2TokenRepresentation representation) {
      this.representation = representation;
   }
}
