"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SERVICE_LOG_ROTATION_MAX_BYTES = void 0;
exports.rotateServiceLogIfNeeded = rotateServiceLogIfNeeded;
exports.rotateServiceLogIfNeededSafely = rotateServiceLogIfNeededSafely;
exports.rotateLogFileIfNeeded = rotateLogFileIfNeeded;
const node_fs_1 = require("node:fs");
const promises_1 = require("node:fs/promises");
const node_path_1 = __importDefault(require("node:path"));
const fs_errors_1 = require("../../core/fs-errors");
const paths_1 = require("../../core/paths");
exports.SERVICE_LOG_ROTATION_MAX_BYTES = 50 * 1024 * 1024;
async function rotateServiceLogIfNeeded(homeDirectory, options = {}) {
    return rotateLogFileIfNeeded((0, paths_1.getServiceLogPath)(homeDirectory), options);
}
async function rotateServiceLogIfNeededSafely(homeDirectory) {
    try {
        await rotateServiceLogIfNeeded(homeDirectory);
    }
    catch (error) {
        console.error(`Failed to rotate service log: ${formatError(error)}`);
    }
}
async function rotateLogFileIfNeeded(logPath, options = {}) {
    const maxBytes = options.maxBytes ?? exports.SERVICE_LOG_ROTATION_MAX_BYTES;
    let fileStat;
    try {
        fileStat = await (0, promises_1.stat)(logPath);
    }
    catch (error) {
        if ((0, fs_errors_1.isMissingFileError)(error)) {
            return null;
        }
        throw error;
    }
    if (!fileStat.isFile() || fileStat.size <= maxBytes) {
        return null;
    }
    await (0, promises_1.mkdir)(node_path_1.default.dirname(logPath), { recursive: true });
    const archivePath = await copyLogToArchive(logPath, options.now ?? new Date());
    await (0, promises_1.truncate)(logPath, 0);
    return archivePath;
}
async function copyLogToArchive(logPath, now) {
    for (let attempt = 0; attempt < 1_000; attempt += 1) {
        const archivePath = buildArchivePath(logPath, now, attempt);
        try {
            await (0, promises_1.copyFile)(logPath, archivePath, node_fs_1.constants.COPYFILE_EXCL);
            return archivePath;
        }
        catch (error) {
            if ((0, fs_errors_1.isAlreadyExistsError)(error)) {
                continue;
            }
            throw error;
        }
    }
    throw new Error(`Could not allocate a rotated service log path for ${logPath}`);
}
function buildArchivePath(logPath, now, attempt) {
    const suffix = attempt === 0 ? "" : `.${attempt}`;
    return `${logPath}.${formatArchiveTimestamp(now)}${suffix}`;
}
function formatArchiveTimestamp(now) {
    return now.toISOString().replace(/[:.]/g, "-");
}
function formatError(error) {
    return error instanceof Error ? error.message : String(error);
}
