/**
 * Replay engine — reconstruct the runtime graph from the event log.
 *
 * The log is the canonical state. The runtime graph in FalkorDB is a
 * projection. This function reads events from the log in order and applies
 * each one to the runtime client, with optional jj-ancestry filtering so
 * branches and abandoned changes don't leak into the current view.
 *
 * See ADR decision #1 (event-sourced state) and #2 (jj change IDs as the
 * time axis). The replay pattern is load-bearing: `indusk graph rebuild`
 * blows away the runtime and calls this to reconstruct it.
 */
import { readEvents } from "./log-reader.js";
/**
 * Replay events from a log file into a runtime graph client.
 *
 * Caller is responsible for calling `client.ensureConnection()` before
 * replay. Caller decides whether to `client.clearGraph()` first (for a full
 * rebuild) or not (for an incremental catch-up).
 */
export async function replay(logPath, client, options = {}) {
    const result = { total: 0, applied: 0, skipped: 0, errors: 0 };
    let lineNumber = 0;
    const onMalformed = (line, err, ln) => {
        result.total++;
        result.errors++;
        if (options.onMalformed) {
            options.onMalformed(line, err, ln);
        }
        else {
            console.error(`[replay] malformed line ${ln}: ${err.message}`);
        }
    };
    for await (const event of readEvents(logPath, { onMalformed })) {
        lineNumber++;
        result.total++;
        // Ancestry filter: if provided, skip events not reachable from HEAD
        if (options.ancestryFilter && !options.ancestryFilter.has(event.change_id)) {
            result.skipped++;
            continue;
        }
        try {
            await client.applyEvent(event);
            result.applied++;
        }
        catch (err) {
            result.errors++;
            const error = err instanceof Error ? err : new Error(String(err));
            if (options.onError) {
                options.onError(error, lineNumber);
            }
            else {
                console.error(`[replay] event ${lineNumber} (${event.type}) failed:`, error.message);
            }
        }
    }
    return result;
}
