import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { mkdtemp, mkdir, readFile, writeFile, readdir } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";

import { ensureLedgerLayout } from "../../ledger/paths.ts";
import { parseMarkdownFrontmatter, renderFrontmatter } from "../../ledger/frontmatter.ts";
import { overruleReviewGate } from "../overruleReviewGate.ts";

describe("overruleReviewGate", () => {
  it("marks REVIEW overruled and restores REPORT valid/status", async () => {
    const root = await mkdtemp(join(tmpdir(), "overrule-gate-"));
    await ensureLedgerLayout(root);
    const reviewsDir = join(root, "fcop", "reviews");
    const reportsDir = join(root, "fcop", "reports");
    const lifecycleActive = join(root, "fcop", "_lifecycle", "active");
    await mkdir(lifecycleActive, { recursive: true });

    const reportId = "REPORT-20260804-007-QA-to-PM";
    const taskId = "TASK-20260804-007";
    await writeFile(
      join(reportsDir, `${reportId}.md`),
      `${renderFrontmatter({
        protocol: "fcop",
        sender: "QA",
        recipient: "PM",
        status: "rejected",
        valid: false,
        invalidated_by: "REVIEW-GATE",
        task_id: taskId,
      })}\n\n## 结论\ndone\n`,
      "utf-8",
    );
    await writeFile(
      join(lifecycleActive, `${taskId}-PM-to-QA.md`),
      `${renderFrontmatter({
        protocol: "fcop",
        task_id: taskId,
        sender: "PM",
        recipient: "QA",
        display_status: "waiting_pm_attention",
        review_status: "rejected",
        pm_attention_reason: "browser_evidence_required",
      })}\n\nbody\n`,
      "utf-8",
    );
    const reviewName = `REVIEW-20260804-001-REVIEW-GATE-on-${taskId}.md`;
    await writeFile(
      join(reviewsDir, reviewName),
      `${renderFrontmatter({
        protocol: "fcop",
        kind: "review",
        reviewer: "REVIEW-GATE",
        decision: "changes_requested",
        suggestion_only: true,
        task_id: taskId,
        report_id: reportId,
        reason_code: "browser_evidence_required",
      })}\n\n# suggestion\n`,
      "utf-8",
    );

    const result = await overruleReviewGate({
      projectRoot: root,
      reviewFilename: reviewName,
      actor: "PM",
      reason: "WP-01 contract QA; no browser required",
    });
    assert.equal(result.ok, true);
    if (!result.ok) return;
    assert.equal(result.report_restored, true);
    assert.equal(result.task_cleared, true);

    const reportFm = parseMarkdownFrontmatter(
      await readFile(join(reportsDir, `${reportId}.md`), "utf-8"),
    );
    assert.equal(reportFm.status, "done");
    assert.equal(reportFm.valid, true);
    assert.equal(reportFm.invalidated_by, undefined);

    const overruledNames = await readdir(join(reviewsDir, "overruled"));
    assert.ok(overruledNames.includes(reviewName));
    const reviewFm = parseMarkdownFrontmatter(
      await readFile(join(reviewsDir, "overruled", reviewName), "utf-8"),
    );
    assert.equal(reviewFm.resolution_status, "overruled");
    assert.equal(reviewFm.overruled_by, "PM");
  });
});
