import assert from "node:assert/strict";
import { mkdtemp, mkdir, writeFile } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { describe, it } from "node:test";
import {
  createGoogleContractState,
  recordGoogleContractHitMaxRounds,
} from "../FcopGoogleRuntimeContract.ts";
import { settleGoogleFcopRun } from "../ReportSettlement.ts";

describe("ReportSettlement", () => {
  it("returns failed when task_id missing", async () => {
    const result = await settleGoogleFcopRun({
      projectRoot: "/tmp",
      agentId: "DEV-01",
    });
    assert.equal(result.ok, false);
    assert.equal(result.status, "failed");
    assert.equal(result.reason, "missing_task_id");
  });

  it("returns done on write_report_submit_done stopReason without report on disk", async () => {
    const state = createGoogleContractState();
    state.hadWriteReportSuccess = true;
    state.hadSubmitTaskSuccess = true;
    state.stopReason = "write_report_submit_done";

    const result = await settleGoogleFcopRun({
      projectRoot: "/tmp/nonexistent",
      agentId: "DEV-01",
      pinnedTaskId: "TASK-20260607-001-ADMIN-to-DEV",
      contractState: state,
      hadToolFailure: true,
      failedToolNames: ["submit_task"],
    });
    assert.equal(result.ok, true);
    assert.equal(result.status, "done");
  });

  it("returns done when report exists and submit already succeeded", async () => {
    const tmp = await mkdtemp(path.join(os.tmpdir(), "cfmu-settle-"));
    const taskId = "TASK-20260607-001-ADMIN-to-DEV";
    const reportsDir = path.join(tmp, "fcop", "reports");
    await mkdir(reportsDir, { recursive: true });
    await writeFile(
      path.join(reportsDir, `REPORT-20260607-001-DEV-to-PM.md`),
      `---\ntask_id: ${taskId}\n---\n# done\n`,
      "utf8",
    );

    const state = createGoogleContractState();
    state.hadSubmitTaskSuccess = true;

    const result = await settleGoogleFcopRun({
      projectRoot: tmp,
      agentId: "DEV-01",
      pinnedTaskId: taskId,
      contractState: state,
    });
    assert.equal(result.ok, true);
    assert.equal(result.status, "done");
  });

  it("auto-writes blocked report when contract failed without report", async () => {
    const tmp = await mkdtemp(path.join(os.tmpdir(), "cfmu-settle-"));
    const taskId = "TASK-20260607-002-ADMIN-to-DEV";
    const calls: Array<{ tool: string; args: Record<string, unknown> }> = [];

    const state = createGoogleContractState();
    recordGoogleContractHitMaxRounds(state);

    const result = await settleGoogleFcopRun({
      projectRoot: tmp,
      agentId: "DEV-01",
      pinnedTaskId: taskId,
      contractState: state,
      hitMaxRounds: true,
      invokeFcop: async (toolName, args) => {
        calls.push({ tool: toolName, args });
        if (toolName === "write_report") {
          return `Wrote REPORT-20260607-002-DEV-to-PM for ${taskId}`;
        }
        return '{"ok":true}';
      },
    });

    assert.equal(result.ok, false);
    assert.equal(result.status, "blocked");
    assert.equal(result.autoReportWritten, true);
    assert.equal(calls.length, 1);
    assert.equal(calls[0]?.tool, "write_report");
    assert.equal(calls[0]?.args.status, "blocked");
  });
});
