"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogDumpService = void 0;
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const logger_1 = require("../logger");
class LogDumpService {
    constructor(options) {
        this.options = options;
        this.logsDirectory = options.logsDirectory;
        this.ensureLogsDirectory();
    }
    async ensureLogsDirectory() {
        try {
            await fs_1.promises.mkdir(this.logsDirectory, { recursive: true });
        }
        catch (error) {
            logger_1.logger.error(`Failed to create logs directory: ${error}`);
        }
    }
    /**
     * Creates a timestamped JSON file with all logs and sends it via email
     */
    async dumpLogsToFile(logs) {
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
        const filename = `logs-dump-${timestamp}.json`;
        const filepath = path_1.default.join(this.logsDirectory, filename);
        try {
            const logDump = {
                dumpTimestamp: new Date().toISOString(),
                totalLogs: logs.length,
                logs: logs,
                metadata: {
                    source: 'log-dump-service',
                    version: '1.0.0'
                }
            };
            await fs_1.promises.writeFile(filepath, JSON.stringify(logDump, null, 2));
            logger_1.logger.info(`Log dump created: ${filepath} with ${logs.length} logs`);
            return filepath;
        }
        catch (error) {
            logger_1.logger.error(`Failed to create log dump file: ${error}`);
            throw error;
        }
    }
    /**
     * Reads all log files and combines them into a single array
     */
    async readAllLogs() {
        const allLogs = [];
        try {
            // Read from private-logs.json
            const privateLogsPath = path_1.default.join(this.logsDirectory, 'private-logs.json');
            const privateLogs = await this.readPrivateLogs(privateLogsPath);
            allLogs.push(...privateLogs);
            // Read from default log files
            const defaultLogsPath = path_1.default.join(this.logsDirectory, 'default');
            const defaultLogs = await this.readDefaultLogs(defaultLogsPath);
            allLogs.push(...defaultLogs);
            // Read from other log files in the directory
            const otherLogs = await this.readOtherLogFiles();
            allLogs.push(...otherLogs);
            logger_1.logger.info(`Collected ${allLogs.length} total logs from all sources`);
            return allLogs;
        }
        catch (error) {
            logger_1.logger.error(`Failed to read logs: ${error}`);
            throw error;
        }
    }
    async readPrivateLogs(filePath) {
        try {
            const content = await fs_1.promises.readFile(filePath, 'utf-8');
            const lines = content.trim().split('\n').filter(line => line.trim());
            const logs = [];
            for (const line of lines) {
                try {
                    const entry = JSON.parse(line);
                    if (entry.logs && Array.isArray(entry.logs)) {
                        logs.push(...entry.logs);
                    }
                }
                catch (parseError) {
                    logger_1.logger.warn(`Failed to parse log line: ${line.substring(0, 100)}...`);
                }
            }
            return logs;
        }
        catch (error) {
            logger_1.logger.warn(`Failed to read private logs: ${error}`);
            return [];
        }
    }
    async readDefaultLogs(defaultLogsPath) {
        const logs = [];
        try {
            const files = await fs_1.promises.readdir(defaultLogsPath);
            for (const file of files) {
                if (file.endsWith('.log')) {
                    const filePath = path_1.default.join(defaultLogsPath, file);
                    const content = await fs_1.promises.readFile(filePath, 'utf-8');
                    const lines = content.trim().split('\n').filter(line => line.trim());
                    for (const line of lines) {
                        try {
                            const logEntry = this.parseLogLine(line);
                            if (logEntry) {
                                logs.push(logEntry);
                            }
                        }
                        catch (parseError) {
                            logger_1.logger.warn(`Failed to parse log line: ${line.substring(0, 100)}...`);
                        }
                    }
                }
            }
        }
        catch (error) {
            logger_1.logger.warn(`Failed to read default logs: ${error}`);
        }
        return logs;
    }
    async readOtherLogFiles() {
        const logs = [];
        try {
            const files = await fs_1.promises.readdir(this.logsDirectory);
            for (const file of files) {
                if (file.endsWith('.log') && !file.includes('private-logs')) {
                    const filePath = path_1.default.join(this.logsDirectory, file);
                    const content = await fs_1.promises.readFile(filePath, 'utf-8');
                    const lines = content.trim().split('\n').filter(line => line.trim());
                    for (const line of lines) {
                        try {
                            const logEntry = this.parseLogLine(line);
                            if (logEntry) {
                                logs.push(logEntry);
                            }
                        }
                        catch (parseError) {
                            logger_1.logger.warn(`Failed to parse log line: ${line.substring(0, 100)}...`);
                        }
                    }
                }
            }
        }
        catch (error) {
            logger_1.logger.warn(`Failed to read other log files: ${error}`);
        }
        return logs;
    }
    parseLogLine(line) {
        try {
            // Try to parse as JSON first
            const jsonMatch = line.match(/^\[DEFAULT\]\s+(.+)$/);
            if (jsonMatch) {
                const jsonPart = jsonMatch[1];
                const timestampMatch = jsonPart.match(/^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}:\d{4})\s+\[(\w+)\]:\s+(.+)$/);
                if (timestampMatch) {
                    const [, timestamp, level, message] = timestampMatch;
                    return {
                        timestamp: new Date(timestamp.replace(/(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2}):(\d{4})/, '$1T$2.$3Z')).toISOString(),
                        level: level.toLowerCase(),
                        message: message,
                        source: 'default-logs'
                    };
                }
            }
            // Fallback: create a basic log entry
            return {
                timestamp: new Date().toISOString(),
                level: 'info',
                message: line,
                source: 'unknown'
            };
        }
        catch (error) {
            return null;
        }
    }
    /**
     * Purges logs older than the specified retention period
     */
    async purgeOldLogs() {
        try {
            const cutoffDate = new Date();
            cutoffDate.setDate(cutoffDate.getDate() - this.options.retentionDays);
            const files = await fs_1.promises.readdir(this.logsDirectory);
            let purgedCount = 0;
            for (const file of files) {
                const filePath = path_1.default.join(this.logsDirectory, file);
                const stats = await fs_1.promises.stat(filePath);
                if (stats.mtime < cutoffDate) {
                    await fs_1.promises.unlink(filePath);
                    purgedCount++;
                    logger_1.logger.info(`Purged old log file: ${file}`);
                }
            }
            logger_1.logger.info(`Purged ${purgedCount} old log files`);
        }
        catch (error) {
            logger_1.logger.error(`Failed to purge old logs: ${error}`);
            throw error;
        }
    }
    /**
     * Gets the size of the logs directory
     */
    async getLogsDirectorySize() {
        try {
            const files = await fs_1.promises.readdir(this.logsDirectory);
            let totalSize = 0;
            for (const file of files) {
                const filePath = path_1.default.join(this.logsDirectory, file);
                const stats = await fs_1.promises.stat(filePath);
                totalSize += stats.size;
            }
            return totalSize;
        }
        catch (error) {
            logger_1.logger.error(`Failed to calculate logs directory size: ${error}`);
            return 0;
        }
    }
}
exports.LogDumpService = LogDumpService;
//# sourceMappingURL=logDumpService.js.map