package de.gecheckt.pdf.umbenenner.bootstrap.adapter;

import java.util.Objects;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import de.gecheckt.pdf.umbenenner.application.port.out.AiContentSensitivity;
import de.gecheckt.pdf.umbenenner.application.port.out.ProcessingLogger;

/**
 * Log4j-based adapter implementing the {@link ProcessingLogger} port.
 * <p>
 * This adapter bridges the application layer to the concrete Log4j2 framework,
 * allowing the application to remain decoupled from logging technology choices.
 * <p>
 * The error method intelligently detects if the last argument is a Throwable
 * and logs accordingly.
 * <p>
 * <h2>Sensitive AI content control</h2>
 * <p>
 * The adapter is initialized with an {@link AiContentSensitivity} setting that
 * controls whether sensitive AI-generated content (complete raw response, reasoning)
 * may be written to log files:
 * <ul>
 *   <li>When set to {@link AiContentSensitivity#PROTECT_SENSITIVE_CONTENT} (default),
 *       calls to {@link #debugSensitiveAiContent(String, Object[])} emit nothing.</li>
 *   <li>When set to {@link AiContentSensitivity#LOG_SENSITIVE_CONTENT}, sensitive
 *       content is logged at DEBUG level.</li>
 * </ul>
 */
public class Log4jProcessingLogger implements ProcessingLogger {

    private final Logger log4jLogger;
    private final AiContentSensitivity aiContentSensitivity;

    /**
     * Creates a logger instance for the given class with default sensitivity setting.
     * <p>
     * Uses {@link AiContentSensitivity#PROTECT_SENSITIVE_CONTENT} as the default.
     *
     * @param clazz the class to derive the logger name from; must not be null
     */
    public Log4jProcessingLogger(Class<?> clazz) {
        this(clazz, AiContentSensitivity.PROTECT_SENSITIVE_CONTENT);
    }

    /**
     * Creates a logger instance for the given class with the specified sensitivity setting.
     *
     * @param clazz the class to derive the logger name from; must not be null
     * @param aiContentSensitivity the sensitivity setting for AI content logging; must not be null
     */
    public Log4jProcessingLogger(Class<?> clazz, AiContentSensitivity aiContentSensitivity) {
        this.log4jLogger = LogManager.getLogger(clazz);
        this.aiContentSensitivity = Objects.requireNonNull(aiContentSensitivity,
                "aiContentSensitivity must not be null");
    }

    @Override
    public void info(String message, Object... args) {
        log4jLogger.info(message, args);
    }

    @Override
    public void debug(String message, Object... args) {
        log4jLogger.debug(message, args);
    }

    @Override
    public void debugSensitiveAiContent(String message, Object... args) {
        // Only log sensitive content if explicitly enabled
        if (aiContentSensitivity == AiContentSensitivity.LOG_SENSITIVE_CONTENT) {
            log4jLogger.debug(message, args);
        }
        // Otherwise emit nothing (protect by default)
    }

    @Override
    public void warn(String message, Object... args) {
        log4jLogger.warn(message, args);
    }

    @Override
    public void error(String message, Object... args) {
        // Log4j2 detects a trailing Throwable in the params array automatically:
        // it uses it as the log cause and formats only the preceding arguments.
        log4jLogger.error(message, args);
    }

}
