import assert from "node:assert/strict";
import { describe, it } from "vitest";
import { handleSupervisedStdinLine } from "../headless-ui.js";

class MockRpcClient {
	prompts: string[] = [];
	steers: string[] = [];
	followUps: string[] = [];
	uiResponses: Array<{
		id: string;
		response: {
			value?: string;
			confirmed?: boolean;
			cancelled?: boolean;
		};
	}> = [];

	prompt(message: string): void {
		this.prompts.push(message);
	}

	steer(message: string): void {
		this.steers.push(message);
	}

	followUp(message: string): void {
		this.followUps.push(message);
	}

	sendUIResponse(
		id: string,
		response: {
			value?: string;
			confirmed?: boolean;
			cancelled?: boolean;
		},
	): void {
		this.uiResponses.push({ id, response });
	}
}

function stderrSink(): { lines: string[]; write: (line: string) => boolean } {
	const lines: string[] = [];
	return {
		lines,
		write(line: string): boolean {
			lines.push(line);
			return true;
		},
	};
}

describe("handleSupervisedStdinLine", () => {
	it("ignores pasted prose without warning spam", () => {
		const client = new MockRpcClient();
		const stderr = stderrSink();

		handleSupervisedStdinLine(
			"rchestrator stdin, skipping",
			client as never,
			() => {},
			stderr,
		);

		assert.deepEqual(stderr.lines, []);
		assert.deepEqual(client.prompts, []);
	});

	it("warns for malformed JSON-RPC-looking orchestrator frames", () => {
		const client = new MockRpcClient();
		const stderr = stderrSink();

		handleSupervisedStdinLine('{"jsonrpc":', client as never, () => {}, stderr);

		assert.equal(stderr.lines.length, 1);
		assert.match(stderr.lines[0] ?? "", /invalid JSON from orchestrator stdin/);
	});

	it("dispatches valid steer frames", () => {
		const client = new MockRpcClient();
		const stderr = stderrSink();

		handleSupervisedStdinLine(
			JSON.stringify({ type: "steer", message: "continue" }),
			client as never,
			() => {},
			stderr,
		);

		assert.deepEqual(client.steers, ["continue"]);
		assert.deepEqual(stderr.lines, []);
	});
});
