"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.appendStructuredLogEntry = exports.pruneExpiredLogArchives = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const zlib = __importStar(require("zlib"));
const log_config_1 = require("./log-config");
const log_paths_1 = require("./log-paths");
const log_buffer_1 = require("./log-buffer");
const log_types_1 = require("./log-types");
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
const PRUNE_INTERVAL_MS = 60 * 1000;
let lastPruneAt = 0;
function getRotateBytes(rotateMb) {
    return Math.max(1, rotateMb) * 1024 * 1024;
}
function rotateCurrentLogIfNeeded() {
    const config = (0, log_config_1.getResolvedLoggingConfig)();
    const currentLogPath = (0, log_paths_1.getCurrentLogPath)();
    if (!fs.existsSync(currentLogPath)) {
        return;
    }
    const stats = fs.statSync(currentLogPath);
    const ageMs = Date.now() - stats.mtimeMs;
    const exceedsSize = stats.size >= getRotateBytes(config.rotate_mb);
    const exceedsAge = ageMs >= ONE_DAY_MS;
    if (!exceedsSize && !exceedsAge) {
        return;
    }
    const currentContent = fs.readFileSync(currentLogPath, 'utf8');
    if (!currentContent.trim()) {
        fs.truncateSync(currentLogPath, 0);
        return;
    }
    const archivePath = (0, log_paths_1.buildArchiveLogPath)(new Date(stats.mtimeMs || Date.now()));
    fs.writeFileSync(archivePath, zlib.gzipSync(currentContent), { mode: 0o600 });
    fs.truncateSync(currentLogPath, 0);
}
function pruneExpiredLogArchives() {
    const config = (0, log_config_1.getResolvedLoggingConfig)();
    const archiveDir = (0, log_paths_1.getLogArchiveDir)();
    if (!fs.existsSync(archiveDir)) {
        return;
    }
    const cutoffMs = Date.now() - config.retain_days * ONE_DAY_MS;
    for (const entry of fs.readdirSync(archiveDir)) {
        const archivePath = path.join(archiveDir, entry);
        try {
            const stats = fs.lstatSync(archivePath);
            if (!stats.isFile() || stats.isSymbolicLink()) {
                continue;
            }
            if (stats.mtimeMs < cutoffMs) {
                fs.unlinkSync(archivePath);
            }
        }
        catch {
            continue;
        }
    }
}
exports.pruneExpiredLogArchives = pruneExpiredLogArchives;
function appendStructuredLogEntry(entry) {
    const config = (0, log_config_1.getResolvedLoggingConfig)();
    if (!config.enabled || !(0, log_types_1.shouldWriteLogLevel)(entry.level, config.level)) {
        return;
    }
    try {
        (0, log_paths_1.ensureLoggingDirectories)();
        rotateCurrentLogIfNeeded();
        fs.appendFileSync((0, log_paths_1.getCurrentLogPath)(), `${JSON.stringify(entry)}\n`, {
            encoding: 'utf8',
            mode: 0o600,
        });
        (0, log_buffer_1.pushRecentLogEntry)(entry, config.live_buffer_size);
        if (Date.now() - lastPruneAt >= PRUNE_INTERVAL_MS) {
            pruneExpiredLogArchives();
            lastPruneAt = Date.now();
        }
    }
    catch {
        // Logging must never break runtime behavior.
    }
}
exports.appendStructuredLogEntry = appendStructuredLogEntry;
//# sourceMappingURL=log-storage.js.map