import path from "node:path";
import { readFile } from "node:fs/promises";
import { nowIso, sanitizeText } from "../../shared/index.js";
import { getRun, listTasks, runDir } from "../run-state/store.js";
export async function checkSeedReportGate(store, runId, input = {}) {
    const dir = runDir(store, runId);
    const [run, tasks, evidenceText, finalReportText] = await Promise.all([
        getRun(store, runId),
        listTasks(store, runId),
        readOptionalText(path.join(dir, "evidence.md")),
        input.content === undefined ? readOptionalText(path.join(dir, "final_report.md")) : Promise.resolve(input.content),
    ]);
    if (!run)
        throw new Error(`SEED run not found: ${runId}`);
    const reportText = finalReportText ?? "";
    const ledgerRefs = matchEvidenceAnchors(evidenceText);
    const citedRefs = matchEvidenceRefs(reportText);
    const taskEvidenceRefs = unique(tasks.flatMap((task) => task.evidence_refs).filter(isEvidenceRef));
    const missingTaskEvidenceRefs = taskEvidenceRefs.filter((ref) => !citedRefs.includes(ref));
    const unknownCitedRefs = citedRefs.filter((ref) => !ledgerRefs.includes(ref));
    const issues = [];
    const warnings = [];
    if (!reportText.trim())
        issues.push("final_report.md is empty or no report content was provided.");
    if (ledgerRefs.length === 0)
        issues.push("No evidence ledger anchors exist yet.");
    if (citedRefs.length === 0)
        issues.push("Final report does not cite any evidence anchors.");
    if (unknownCitedRefs.length > 0)
        issues.push(`Final report cites unknown evidence anchors: ${unknownCitedRefs.join(", ")}.`);
    if (missingTaskEvidenceRefs.length > 0)
        issues.push(`Final report is missing task evidence anchors: ${missingTaskEvidenceRefs.join(", ")}.`);
    if (taskEvidenceRefs.length === 0 && ledgerRefs.length > 0)
        warnings.push("No task is linked to an evidence anchor yet.");
    return {
        schema_version: 1,
        checked_at: nowIso(),
        run_id: run.run_id,
        required: input.required ?? false,
        status: issues.length === 0 ? "passed" : "failed",
        report: {
            source: input.content === undefined ? "final_report.md" : "provided_content",
            has_content: reportText.trim().length > 0,
            cited_evidence_refs: citedRefs,
        },
        evidence: {
            ledger_refs: ledgerRefs,
            task_evidence_refs: taskEvidenceRefs,
            missing_task_evidence_refs: missingTaskEvidenceRefs,
            unknown_cited_refs: unknownCitedRefs,
        },
        issues: issues.map(sanitizeText),
        warnings: warnings.map(sanitizeText),
    };
}
function matchEvidenceAnchors(text) {
    return unique([...text.matchAll(/<a id="([^"]+)"><\/a>/g)].map((match) => `evidence.md#${match[1]}`));
}
function matchEvidenceRefs(text) {
    return unique([...text.matchAll(/evidence\.md#[A-Za-z0-9_.-]+/g)].map((match) => match[0]));
}
function isEvidenceRef(ref) {
    return /^evidence\.md#[A-Za-z0-9_.-]+$/.test(ref);
}
function unique(values) {
    return [...new Set(values.filter(Boolean))].sort();
}
async function readOptionalText(file) {
    try {
        return await readFile(file, "utf8");
    }
    catch (error) {
        if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
            return "";
        throw error;
    }
}
//# sourceMappingURL=index.js.map