package com.airlock.iam.oauth2.application.configuration.logging;

import com.airlock.iam.oauth2.domain.model.logging.HidingTokenRepresentation;
import com.airlock.iam.oauth2.domain.model.logging.OAuth2TokenRepresentation;
import com.airlock.iam.plugin.api.annotation.config.Plugin;
import com.airlock.iam.plugin.api.annotation.license.PluginLicenseRestriction;
import com.airlock.iam.plugin.api.annotation.property.BooleanProperty;
import com.airlock.iam.plugin.api.annotation.property.PluginProperty;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Optional;

@Plugin(
   description = "Configures OAuth 2.0 logging behaviour for integration or error diagnostics. <p><b>Be aware</b> that this settings are not meant for productive service unless it is required for error diagnostics.</p>",
   displayName = "OAuth 2.0 Logging Settings"
)
@PluginLicenseRestriction(moduleAffiliation = {"OAuthServer", "OAuthClient"})
public final class OAuth2LoggingSettings {
   @BooleanProperty(
      description = "If enabled, all DEBUG logs are written to INFO instead. <p><b>Be aware</b> that logging DEBUG information is detrimental to security because sensitive data might be logged. In addition, increased log output decreases the performance of the system</p>",
      optional = true,
      displayName = "DEBUG Logs On INFO",
      defaultValue = "false"
   )
   private boolean logOnInfo;
   @PluginProperty(
      description = "Configures how many characters of OAuth 2.0 Tokens are logged, e.g. during Token Introspection, Token Refresh or when receiving tokens as a client. If not configured, token content is always hidden in logs.<br/><br/><strong>Security implications</strong>: Logging token information is detrimental to security. The logs will contain parts of OAuth 2.0 Tokens, which is generally not recommended. This increases the probability of guessing correct tokens for attackers with log access.<br/>Especially in cases where tokens (e.g. Refresh Tokens) are long living, we advise against using this feature.",
      displayName = "Token Logging Strategy",
      optional = true
   )
   private OAuth2TokenLoggingStrategy strategy;

   public OAuth2TokenRepresentation tokenRepresentation() {
      return Optional.ofNullable(this.strategy).map(OAuth2TokenLoggingStrategy::tokenRepresentation).orElse(new HidingTokenRepresentation());
   }

   public boolean isLogOnInfo() {
      return this.logOnInfo;
   }

   public OAuth2TokenLoggingStrategy getStrategy() {
      return this.strategy;
   }

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

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2LoggingSettings(boolean logOnInfo, OAuth2TokenLoggingStrategy strategy) {
      this.logOnInfo = logOnInfo;
      this.strategy = strategy;
   }

   @SuppressFBWarnings(justification = "generated code")
   public OAuth2LoggingSettings() {
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class OAuth2LoggingSettingsBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private boolean logOnInfo;
      @SuppressFBWarnings(justification = "generated code")
      private OAuth2TokenLoggingStrategy strategy;

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

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2LoggingSettings.OAuth2LoggingSettingsBuilder logOnInfo(boolean logOnInfo) {
         this.logOnInfo = logOnInfo;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2LoggingSettings.OAuth2LoggingSettingsBuilder strategy(OAuth2TokenLoggingStrategy strategy) {
         this.strategy = strategy;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public OAuth2LoggingSettings build() {
         return new OAuth2LoggingSettings(this.logOnInfo, this.strategy);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "OAuth2LoggingSettings.OAuth2LoggingSettingsBuilder(logOnInfo=" + this.logOnInfo + ", strategy=" + this.strategy + ")";
      }
   }
}
