/**
 * Regression guard: cancelled units must not create normal auto-commits.
 *
 * A runaway-paused execute-task can return `status: "cancelled"` after the
 * agent has staged work. That state is recovery territory, not a completed
 * task. The cancelled branch must clear the deferred-commit flag and leave
 * the operator/recovery path to decide what to do with the patch.
 */

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { test } from 'vitest';

const src = readFileSync(
	join(import.meta.dirname, "..", "auto", "phases.ts"),
	"utf-8",
);

function cancelledBranchBody(): string {
	const marker = 'if (unitResult.status === "cancelled") {';
	const start = src.indexOf(marker);
	assert.notEqual(start, -1, "cancelled-unit branch must exist");
	const nextMarker = "\n\t// \u2500\u2500 Immediate unit closeout";
	const end = src.indexOf(nextMarker, start);
	assert.notEqual(end, -1, "cancelled-unit branch end marker must exist");
	return src.slice(start, end);
}

test("cancelled unit branch does not call autoCommitUnit", () => {
	const body = cancelledBranchBody();
	assert.equal(
		body.includes("autoCommitUnit"),
		false,
		"cancelled units must not call normal autoCommitUnit",
	);
});

test("cancelled unit branch clears deferred commit state before returning", () => {
	const body = cancelledBranchBody();
	const callIndex = body.indexOf("clearDeferredCommitAfterCancelledUnit(");
	assert.ok(callIndex >= 0, "cancelled units must clear deferred commit state");
	const providerReturnIndex = body.indexOf('reason: "provider-pause"');
	assert.ok(
		providerReturnIndex > callIndex,
		"deferred commit state must be cleared before provider cancellation exits",
	);
	const timeoutReturnIndex = body.indexOf('reason: "session-timeout"');
	assert.ok(
		timeoutReturnIndex > callIndex,
		"deferred commit state must be cleared before timeout cancellation exits",
	);
	const failedReturnIndex = body.indexOf('reason: "session-failed"');
	assert.ok(
		failedReturnIndex > callIndex,
		"deferred commit state must be cleared before failed cancellation exits",
	);
});

test("cancelled unit clear helper resets commit flags without committing", () => {
	const helperName = "function clearDeferredCommitAfterCancelledUnit";
	const start = src.indexOf(helperName);
	assert.notEqual(start, -1, "clear helper must exist");
	const end = src.indexOf("\n}\n", start + helperName.length);
	assert.notEqual(end, -1, "clear helper must have a body");
	const helper = src.slice(start, end);
	assert.ok(
		helper.includes("s.stagedPendingCommit = false"),
		"helper must clear stagedPendingCommit",
	);
	assert.ok(
		helper.includes("s.pendingCommitTaskContext = null"),
		"helper must clear pendingCommitTaskContext",
	);
	assert.equal(
		helper.includes("commitStaged(") || helper.includes("autoCommit"),
		false,
		"clear helper must not commit",
	);
});
