/**
 * @plan PLAN-20250120-DEBUGLOGGING.P05
 * @requirement REQ-001,REQ-002,REQ-006
 * @pseudocode lines 10-121
 */
import createDebug from 'debug';
import { ConfigurationManager } from './ConfigurationManager.js';
import { FileOutput } from './FileOutput.js';
// Configure debug to use console.log instead of stderr for React UI compatibility
// This ensures debug output goes to the Ctrl+O debug console in the UI
if (typeof window === 'undefined') {
    // Disable colors to respect theme settings
    createDebug.useColors = () => false;
    // Use a wrapper function that calls the CURRENT console.log
    // This works even if console.log is patched later by the UI
    createDebug.log = (...args) => {
        // Call whatever console.log is at the time of logging
        // This allows the UI's ConsolePatcher to intercept it
        console.log(...args);
    };
}
export class DebugLogger {
    debugInstance; // Line 11
    _namespace; // Line 12
    _configManager; // Line 13
    _fileOutput; // Line 14
    _enabled; // Line 15
    _level = 'debug';
    constructor(namespace) {
        // Lines 17-24: Initialize logger
        this._namespace = namespace; // Line 18
        this.debugInstance = createDebug(namespace); // Line 19
        this._configManager = ConfigurationManager.getInstance(); // Line 20
        this._fileOutput = FileOutput.getInstance(); // Line 21
        this._enabled = this.checkEnabled(); // Line 22
        this._configManager.subscribe(() => this.onConfigChange()); // Line 23
    }
    get namespace() {
        return this._namespace;
    }
    get enabled() {
        return this._enabled;
    }
    set enabled(value) {
        this._enabled = value;
    }
    get level() {
        return this._level;
    }
    set level(value) {
        this._level = value;
    }
    get configManager() {
        return this._configManager;
    }
    get fileOutput() {
        return this._fileOutput;
    }
    log(messageOrFn, ...args) {
        // Lines 26-60: Main log method
        if (!this._enabled) {
            // Line 27-29
            return; // Zero overhead - no processing when disabled
        }
        let message;
        if (typeof messageOrFn === 'function') {
            // Line 32
            try {
                message = messageOrFn(); // Line 34
            }
            catch (_error) {
                message = '[Error evaluating log function]'; // Line 36
            }
        }
        else {
            message = messageOrFn; // Line 39
        }
        message = this.redactSensitive(message); // Line 42
        const timestamp = new Date().toISOString(); // Line 43
        const logEntry = {
            // Lines 45-51
            timestamp,
            namespace: this._namespace,
            level: 'log',
            message,
            args: args.length > 0 ? args : undefined,
        };
        const target = this._configManager.getOutputTarget();
        if (target.includes('file')) {
            // Line 53-55
            void this._fileOutput.write(logEntry);
        }
        if (target.includes('stderr')) {
            // Line 57-59
            this.debugInstance(message, ...args);
        }
    }
    debug(messageOrFn, ...args) {
        // Lines 62-64
        if (this._level === 'error') {
            return; // Don't log debug messages when level is error
        }
        // Create modified log entry with debug level
        if (!this._enabled) {
            return;
        }
        let message;
        if (typeof messageOrFn === 'function') {
            try {
                message = messageOrFn();
            }
            catch (_error) {
                message = '[Error evaluating log function]';
            }
        }
        else {
            message = messageOrFn;
        }
        message = this.redactSensitive(message);
        const timestamp = new Date().toISOString();
        const logEntry = {
            timestamp,
            namespace: this._namespace,
            level: 'debug',
            message,
            args: args.length > 0 ? args : undefined,
        };
        const target = this._configManager.getOutputTarget();
        if (target.includes('file')) {
            void this._fileOutput.write(logEntry);
        }
        if (target.includes('stderr')) {
            this.debugInstance(message, ...args);
        }
    }
    warn(messageOrFn, ...args) {
        // Use error level for warnings for now
        this.error(messageOrFn, ...args);
    }
    error(messageOrFn, ...args) {
        // Lines 66-70
        if (!this._enabled) {
            return;
        }
        let message;
        if (typeof messageOrFn === 'function') {
            try {
                message = messageOrFn();
            }
            catch (_error) {
                message = '[Error evaluating log function]';
            }
        }
        else {
            message = messageOrFn;
        }
        message = this.redactSensitive(message);
        const timestamp = new Date().toISOString();
        const logEntry = {
            timestamp,
            namespace: this._namespace,
            level: 'error',
            message,
            args: args.length > 0 ? args : undefined,
        };
        const target = this._configManager.getOutputTarget();
        if (target.includes('file')) {
            void this._fileOutput.write(logEntry);
        }
        if (target.includes('stderr')) {
            this.debugInstance(message, ...args);
        }
    }
    checkEnabled() {
        // Lines 72-85: Check if logger enabled
        const config = this._configManager.getEffectiveConfig(); // Line 73
        if (!config.enabled) {
            // Line 74-76
            return false;
        }
        // Handle namespaces as either array or object
        const namespaces = Array.isArray(config.namespaces)
            ? config.namespaces
            : Object.keys(config.namespaces);
        for (const pattern of namespaces) {
            // Line 78-82
            if (this.matchesPattern(this._namespace, pattern)) {
                return true;
            }
        }
        return false; // Line 84
    }
    matchesPattern(namespace, pattern) {
        // Lines 87-98: Pattern matching
        if (pattern === namespace) {
            // Line 88-90
            return true;
        }
        // Support wildcards anywhere in the pattern
        if (pattern.includes('*')) {
            // Convert pattern to regex:
            // - Escape special regex chars except *
            // - Replace * with .* for regex wildcard matching
            const regexPattern = pattern
                .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special chars
                .replace(/\*/g, '.*'); // Convert * to regex wildcard
            const regex = new RegExp(`^${regexPattern}$`);
            return regex.test(namespace);
        }
        return false; // Line 97
    }
    redactSensitive(message) {
        // Lines 100-110: Redact sensitive data
        const patterns = this._configManager.getRedactPatterns(); // Line 101
        let result = message; // Line 102
        for (const pattern of patterns) {
            // Line 104-107
            const regex = new RegExp(`${pattern}["']?:\\s*["']?([^"'\\s]+)`, 'gi');
            result = result.replace(regex, `${pattern}: [REDACTED]`);
        }
        return result; // Line 109
    }
    onConfigChange() {
        // Lines 112-114
        this._enabled = this.checkEnabled();
    }
    async dispose() {
        // Lines 116-119
        this._configManager.unsubscribe(this.onConfigChange);
        // Flush pending writes handled by FileOutput
        await this._fileOutput.dispose();
    }
}
//# sourceMappingURL=DebugLogger.js.map