/**
 * Run log — append-only NDJSON log of cron job executions.
 *
 * Each job gets its own log file: cron/runs/<jobId>.ndjson
 * One line per execution with timestamp, status, duration, and error.
 */
import fs from 'node:fs';
import path from 'node:path';
import { getCronDir } from './store.js';
function getRunsDir() {
    return path.join(getCronDir(), 'runs');
}
/** Max output stored per run (truncated beyond this). */
const MAX_LOG_OUTPUT = 4096;
/** Truncate output for storage. */
export function truncateRunOutput(text) {
    if (text.length <= MAX_LOG_OUTPUT)
        return text;
    return text.slice(0, MAX_LOG_OUTPUT) + '\n... (truncated)';
}
/** Append a run log entry for a completed job. */
export async function appendRunLog(entry, runsDir = getRunsDir()) {
    await fs.promises.mkdir(runsDir, { recursive: true, mode: 0o700 });
    const logPath = path.join(runsDir, `${entry.jobId}.ndjson`);
    const line = JSON.stringify(entry) + '\n';
    await fs.promises.appendFile(logPath, line, { encoding: 'utf-8', mode: 0o600 });
}
/** Read recent run log entries for a job (newest first, up to limit). */
export async function readRunLog(jobId, limit = 20, runsDir = getRunsDir()) {
    const logPath = path.join(runsDir, `${jobId}.ndjson`);
    let raw;
    try {
        raw = await fs.promises.readFile(logPath, 'utf-8');
    }
    catch {
        return [];
    }
    const lines = raw.trim().split('\n').filter(Boolean);
    const entries = [];
    // Read from end for newest-first
    for (let i = lines.length - 1; i >= 0 && entries.length < limit; i--) {
        try {
            entries.push(JSON.parse(lines[i]));
        }
        catch {
            // Skip corrupt lines
        }
    }
    return entries;
}
//# sourceMappingURL=run-log.js.map