"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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseDurationToSeconds = parseDurationToSeconds;
exports.collectLogs = collectLogs;
exports.renderLogsHuman = renderLogsHuman;
exports.renderLogsJson = renderLogsJson;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const DEFAULT_TAIL = 20;
const KNOWN_JSONL_FILES = [
    'governance-ledger.jsonl',
    'media-routing.log.jsonl',
    'capability-lifecycle.jsonl',
    'canonization-log.jsonl',
];
function parseDurationToSeconds(input) {
    const trimmed = input.trim().toLowerCase();
    const m = trimmed.match(/^(\d+)\s*(s|m|h|d)$/);
    if (!m)
        return null;
    const n = Number.parseInt(m[1], 10);
    if (!Number.isFinite(n) || n < 0)
        return null;
    const unit = m[2];
    const mult = unit === 's' ? 1 : unit === 'm' ? 60 : unit === 'h' ? 3600 : 86400;
    return n * mult;
}
function entrySubsystem(filePath) {
    const base = path.basename(filePath);
    return base.replace(/\.log\.jsonl$/, '').replace(/\.jsonl$/, '');
}
function extractTs(parsed, fallbackMtime) {
    if (!parsed)
        return fallbackMtime;
    if (typeof parsed.ts === 'string') {
        const t = Date.parse(parsed.ts);
        if (!Number.isNaN(t))
            return t;
    }
    if (typeof parsed.ts === 'number' && Number.isFinite(parsed.ts)) {
        return parsed.ts > 1e12 ? parsed.ts : parsed.ts * 1000;
    }
    if (typeof parsed.timestamp === 'string') {
        const t = Date.parse(parsed.timestamp);
        if (!Number.isNaN(t))
            return t;
    }
    return fallbackMtime;
}
function summarizeEntry(parsed) {
    if (!parsed)
        return '<unparseable line>';
    const candidates = [
        parsed.summary,
        parsed.decision?.auditSummary,
        parsed.message,
        parsed.action,
        parsed.event,
        parsed.type,
    ];
    for (const c of candidates) {
        if (typeof c === 'string' && c.trim().length > 0) {
            return c.length > 140 ? `${c.slice(0, 137)}...` : c;
        }
    }
    // Fall back to a one-line preview of the parsed object.
    const compact = JSON.stringify(parsed);
    return compact.length > 140 ? `${compact.slice(0, 137)}...` : compact;
}
function listJsonlFiles(stateDir) {
    if (!fs.existsSync(stateDir))
        return [];
    try {
        const entries = fs.readdirSync(stateDir);
        const found = [];
        for (const e of entries) {
            if (KNOWN_JSONL_FILES.includes(e) || e.endsWith('.jsonl')) {
                found.push(path.join(stateDir, e));
            }
        }
        return found;
    }
    catch {
        return [];
    }
}
function collectLogs(opts = {}) {
    const root = opts.root || process.cwd();
    const stateDir = process.env.OPENLIFE_STATE_DIR
        ? path.resolve(process.env.OPENLIFE_STATE_DIR)
        : path.join(root, '.openlife');
    const files = listJsonlFiles(stateDir);
    const filter = opts.filter ? opts.filter.toLowerCase() : null;
    const tail = opts.tail && opts.tail > 0 ? opts.tail : DEFAULT_TAIL;
    const sinceSeconds = opts.since ? parseDurationToSeconds(opts.since) : null;
    const minTs = sinceSeconds !== null ? Date.now() - sinceSeconds * 1000 : null;
    const out = [];
    for (const fp of files) {
        const subsystem = entrySubsystem(fp);
        if (filter && !subsystem.toLowerCase().includes(filter))
            continue;
        let mtime = Date.now();
        try {
            mtime = fs.statSync(fp).mtimeMs;
        }
        catch {
            continue;
        }
        let raw = '';
        try {
            raw = fs.readFileSync(fp, 'utf-8');
        }
        catch {
            continue;
        }
        const lines = raw.split('\n').filter((l) => l.trim().length > 0);
        for (const line of lines) {
            let parsed = null;
            try {
                parsed = JSON.parse(line);
            }
            catch {
                parsed = null;
            }
            const ts = extractTs(parsed, mtime);
            if (minTs !== null && ts < minTs)
                continue;
            out.push({ subsystem, rawLine: line, parsed, ts });
        }
    }
    out.sort((a, b) => a.ts - b.ts);
    return out.slice(-tail);
}
function renderLogsHuman(entries) {
    if (entries.length === 0)
        return '(no entries match filter)';
    return entries
        .map((e) => {
        const tsIso = new Date(e.ts).toISOString();
        return `${tsIso}  [${e.subsystem}]  ${summarizeEntry(e.parsed)}`;
    })
        .join('\n');
}
function renderLogsJson(entries) {
    return entries
        .map((e) => JSON.stringify({ ts: new Date(e.ts).toISOString(), subsystem: e.subsystem, entry: e.parsed ?? e.rawLine }))
        .join('\n');
}
