package com.airlock.iam.common.infrastructure.logger;

import com.airlock.iam.base.api.domain.model.user.UserId;
import com.airlock.iam.base.misc.log.LogUtil;
import com.airlock.iam.log.api.helpdesk.HelpdeskLogger;
import com.airlock.iam.log.processor.LogMessageProcessor;
import com.airlock.iam.log.usertrail.UserTrailLogger;
import com.google.common.annotations.VisibleForTesting;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import org.apache.commons.lang3.StringUtils;

public class RestHelpdeskLogger implements HelpdeskLogger {
   private final Provider<String> authentee;
   private final Provider<LogMessageProcessor> logMessageProcessor;

   @Inject
   public RestHelpdeskLogger(Provider<String> authentee, Provider<LogMessageProcessor> logMessageProcessor) {
      this.authentee = authentee;
      this.logMessageProcessor = logMessageProcessor;
   }

   public void log(String affectedUser, String message) {
      String logMessage = this.replacePlaceholders(affectedUser, message);
      String adaptedLogMessage = ((LogMessageProcessor)this.logMessageProcessor.get()).adaptLogMessage(logMessage);
      UserTrailLogger.log(LogUtil.logSafeString(affectedUser), adaptedLogMessage);
   }

   public void log(@Nullable UserId affectedUser, String message) {
      this.log(affectedUser == null ? null : affectedUser.getValue(), message);
   }

   @SuppressFBWarnings("FORMAT_STRING_MANIPULATION")
   public void log(String affectedUser, String messageFormat, Object... args) {
      this.log(affectedUser, String.format(messageFormat, args));
   }

   public void log(@Nullable UserId affectedUser, String messageFormat, Object... args) {
      this.log(affectedUser == null ? null : affectedUser.getValue(), messageFormat, args);
   }

   @VisibleForTesting
   String replacePlaceholders(String affectedUser, String message) {
      String result = message;
      if (result.contains("${authentee}")) {
         result = result.replace("${authentee}", StringUtils.wrap(LogUtil.logSafeString((String)this.authentee.get()), '"'));
      }

      return result.replace("${affectedUser}", StringUtils.wrap(affectedUser != null ? LogUtil.logSafeString(affectedUser) : "unknown", '"'));
   }
}
