import { promises as fs } from 'node:fs';
import { join } from 'node:path';
import { parseWorkflowDefinition } from './definition.js';
import { EventLog } from './events/append.js';
import { replay } from './events/replay.js';
import { getRunsDir } from './runs-dir.js';
import { readRunChatBinding } from './loader.js';
export async function scanColdWorkflowRuns(opts) {
    const runsDir = opts.runsDir ?? getRunsDir();
    let entries;
    try {
        entries = await fs.readdir(runsDir, { withFileTypes: true });
    }
    catch (err) {
        if (err.code === 'ENOENT')
            return [];
        throw err;
    }
    const out = [];
    for (const entry of entries) {
        if (!entry.isDirectory())
            continue;
        const runId = entry.name;
        const dir = join(runsDir, runId);
        let binding;
        try {
            binding = await readRunChatBinding(runId, { runDir: dir });
        }
        catch {
            opts.onSkip?.(runId, 'missing-or-invalid-chat-binding');
            continue;
        }
        if (binding.larkAppId !== opts.ownerLarkAppId) {
            opts.onSkip?.(runId, 'owned-by-another-lark-app');
            continue;
        }
        let def;
        try {
            const raw = await fs.readFile(join(dir, 'workflow.json'), 'utf-8');
            def = parseWorkflowDefinition(JSON.parse(raw));
        }
        catch (err) {
            opts.onSkip?.(runId, `invalid-workflow-json: ${err instanceof Error ? err.message : String(err)}`);
            continue;
        }
        let snapshot;
        try {
            const log = new EventLog(runId, runsDir);
            const events = await log.readAll();
            if (events.length === 0) {
                opts.onSkip?.(runId, 'empty-event-log');
                continue;
            }
            snapshot = replay(events);
        }
        catch (err) {
            opts.onSkip?.(runId, `unreplayable-event-log: ${err instanceof Error ? err.message : String(err)}`);
            continue;
        }
        if (snapshot.run.status === 'succeeded' ||
            snapshot.run.status === 'failed' ||
            snapshot.run.status === 'cancelled') {
            opts.onSkip?.(runId, `terminal-${snapshot.run.status}`);
            continue;
        }
        out.push({ runId, def, snapshot, binding });
    }
    return out;
}
//# sourceMappingURL=cold-scan.js.map