/**
 * Logger - File-Based Logging System
 * Logs to files with rotation, retention policies, and multiple log levels
 */
import * as fs from '../../node-singletons/fs.js';
import * as path from '../../node-singletons/path.js';
const levelPriority = {
    debug: 0,
    info: 1,
    warn: 2,
    error: 3,
};
const ensureLogsDir = (logsDir) => {
    if (!fs.existsSync(logsDir)) {
        fs.mkdirSync(logsDir, { recursive: true });
    }
};
const getLogFilePath = (logsDir, category = 'app') => {
    return path.join(logsDir, `${category}.log`);
};
const writeToLogFile = (logsDir, maxFileSize, entry, category = 'app') => {
    ensureLogsDir(logsDir);
    const logFile = getLogFilePath(logsDir, category);
    const logString = JSON.stringify(entry) + '\n';
    try {
        // Check file size for rotation
        if (fs.existsSync(logFile)) {
            const stats = fs.statSync(logFile);
            if (stats.size > maxFileSize) {
                const timestamp = new Date().toISOString().replaceAll(/[:.]/g, '-');
                fs.renameSync(logFile, `${logFile}.${timestamp}.bak`);
            }
        }
        fs.appendFileSync(logFile, logString);
    }
    catch (error) {
        // Fallback to stderr if file logging fails
        process.stderr.write(`Failed to write to log file: ${String(error)}\n`);
    }
};
const log = (logsDir, maxFileSize, currentLevel, logLevel, message, data, category = 'app') => {
    if (levelPriority[logLevel] < levelPriority[currentLevel]) {
        return;
    }
    const entry = {
        timestamp: new Date().toISOString(),
        level: logLevel,
        message,
        data,
        context: category,
    };
    writeToLogFile(logsDir, maxFileSize, entry, category);
};
export const Logger = Object.freeze({
    /**
     * Create a new logger instance
     */
    create(logsDir = path.join(process.cwd(), 'logs'), maxFileSize = 10 * 1024 * 1024, // 10MB
    level = 'info') {
        return {
            debug(message, data, category) {
                log(logsDir, maxFileSize, level, 'debug', message, data, category);
            },
            info(message, data, category) {
                log(logsDir, maxFileSize, level, 'info', message, data, category);
            },
            warn(message, data, category) {
                log(logsDir, maxFileSize, level, 'warn', message, data, category);
            },
            error(message, data, category) {
                log(logsDir, maxFileSize, level, 'error', message, data, category);
            },
            getLogs(category = 'app', limit = 100) {
                const logFile = getLogFilePath(logsDir, category);
                if (!fs.existsSync(logFile))
                    return [];
                try {
                    const content = fs.readFileSync(logFile, 'utf-8');
                    return content
                        .split('\n')
                        .filter((line) => line.trim() !== '')
                        .map((line) => JSON.parse(line))
                        .reverse()
                        .slice(0, limit);
                }
                catch (error) {
                    process.stderr.write(`Failed to read logs: ${String(error)}\n`);
                    return [];
                }
            },
            filterByLevel(logs, filterLevel) {
                return logs.filter((l) => l.level === filterLevel);
            },
            filterByDateRange(logs, startDate, endDate) {
                return logs.filter((l) => {
                    const date = new Date(l.timestamp);
                    return date >= startDate && date <= endDate;
                });
            },
            clearLogs(category = 'app') {
                const logFile = getLogFilePath(logsDir, category);
                if (fs.existsSync(logFile)) {
                    fs.unlinkSync(logFile);
                    return true;
                }
                return false;
            },
            getLogsDirectory() {
                return logsDir;
            },
            getLogLevel() {
                return level;
            },
        };
    },
    /**
     * Get singleton instance
     */
    getInstance() {
        globalThis.__loggerInstance ??= this.create();
        return globalThis.__loggerInstance;
    },
    // Static-like methods for convenience
    debug(message, data, category) {
        this.getInstance().debug(message, data, category);
    },
    info(message, data, category) {
        this.getInstance().info(message, data, category);
    },
    warn(message, data, category) {
        this.getInstance().warn(message, data, category);
    },
    error(message, data, category) {
        this.getInstance().error(message, data, category);
    },
});
export default Logger;
