import fs from "node:fs/promises";
import path from "node:path";
import crypto from "node:crypto";
import { LINEAGE_SCHEMA_VERSION, lineageCorrelationRoot } from "./lineage-contract.js";
const LINEAGE_DIR = ".workspace-kit/lineage";
const EVENTS_FILE = "events.jsonl";
function eventsPath(workspacePath) {
    return path.join(workspacePath, LINEAGE_DIR, EVENTS_FILE);
}
export function newLineageEventId() {
    return `lev-${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;
}
export async function appendLineageEvent(workspacePath, input) {
    const timestamp = input.timestamp ?? new Date().toISOString();
    const correlationRoot = lineageCorrelationRoot(input.recommendationTaskId, input.evidenceKey);
    const event = {
        schemaVersion: LINEAGE_SCHEMA_VERSION,
        eventId: input.eventId ?? newLineageEventId(),
        eventType: input.eventType,
        timestamp,
        correlationRoot,
        payload: input.payload
    };
    const fp = eventsPath(workspacePath);
    await fs.mkdir(path.dirname(fp), { recursive: true });
    await fs.appendFile(fp, `${JSON.stringify(event)}\n`, "utf8");
    return event;
}
export async function readLineageEvents(workspacePath) {
    const fp = eventsPath(workspacePath);
    let raw;
    try {
        raw = await fs.readFile(fp, "utf8");
    }
    catch (e) {
        if (e.code === "ENOENT")
            return [];
        throw e;
    }
    const out = [];
    for (const line of raw.split("\n")) {
        const t = line.trim();
        if (!t)
            continue;
        try {
            const ev = JSON.parse(t);
            if (ev.schemaVersion === LINEAGE_SCHEMA_VERSION)
                out.push(ev);
        }
        catch {
            /* skip corrupt line */
        }
    }
    return out;
}
/** Reconstruct rec → dec → app chain for a recommendation task id (deterministic sort by timestamp). */
export async function queryLineageChain(workspacePath, recommendationTaskId) {
    const all = await readLineageEvents(workspacePath);
    const chain = all.filter((e) => {
        const p = e.payload;
        return p.recommendationTaskId === recommendationTaskId;
    });
    chain.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
    const byType = {
        rec: [],
        dec: [],
        app: [],
        corr: []
    };
    for (const e of chain) {
        byType[e.eventType].push(e);
    }
    return { events: chain, byType };
}
