import assert from "node:assert/strict";
import { describe, test } from "vitest";

/**
 * Tests for the boot route's null-project path.
 *
 * When no SF_WEB_PROJECT_CWD is set and no ?project param is present,
 * the boot route returns a canned "no project" payload so the frontend
 * can show the project picker. These tests verify the shape and values
 * of that payload without requiring bridge/subprocess.
 *
 * See: web/app/api/boot/route.ts — null-project early return branch.
 */

/** Mirrors the null-project payload returned by the boot route. */
function makeNullProjectPayload() {
	return {
		project: null,
		workspace: null,
		auto: null,
		onboarding: { locked: false },
		onboardingNeeded: false,
		resumableSessions: [],
		bridge: null,
		projectDetection: null,
	};
}

/**
 * Mirrors resolveProjectCwd URL-parsing logic from bridge-service.ts.
 * Returns the ?project query param value, or null if absent/malformed.
 */
function resolveProjectFromUrl(requestUrl: string): string | null {
	try {
		const url = new URL(requestUrl);
		const projectParam = url.searchParams.get("project");
		if (projectParam) return decodeURIComponent(projectParam);
	} catch {
		// Malformed URL — fall through
	}
	return null;
}

describe("boot route — null-project payload shape", () => {
	test("nullProjectPayload_always_hasNullTopLevelFields", () => {
		const payload = makeNullProjectPayload();
		assert.equal(payload.project, null);
		assert.equal(payload.workspace, null);
		assert.equal(payload.auto, null);
		assert.equal(payload.bridge, null);
		assert.equal(payload.projectDetection, null);
	});

	test("nullProjectPayload_always_hasOnboardingNotLocked", () => {
		const payload = makeNullProjectPayload();
		assert.deepEqual(payload.onboarding, { locked: false });
	});

	test("nullProjectPayload_always_hasOnboardingNeededFalse", () => {
		const payload = makeNullProjectPayload();
		assert.equal(payload.onboardingNeeded, false);
	});

	test("nullProjectPayload_always_hasEmptyResumableSessions", () => {
		const payload = makeNullProjectPayload();
		assert.deepEqual(payload.resumableSessions, []);
	});
});

describe("boot route — resolveProjectCwd URL parsing", () => {
	test("resolveProjectFromUrl_whenProjectParamPresent_returnsDecodedValue", () => {
		const result = resolveProjectFromUrl(
			"http://localhost:3000/api/boot?project=%2Fhome%2Fuser%2Fproject",
		);
		assert.equal(result, "/home/user/project");
	});

	test("resolveProjectFromUrl_whenNoProjectParam_returnsNull", () => {
		const result = resolveProjectFromUrl("http://localhost:3000/api/boot");
		assert.equal(result, null);
	});

	test("resolveProjectFromUrl_whenProjectParamIsEmpty_returnsNull", () => {
		// Empty ?project= param → searchParams.get returns "" → falsy → null
		const result = resolveProjectFromUrl(
			"http://localhost:3000/api/boot?project=",
		);
		assert.equal(result, null);
	});

	test("resolveProjectFromUrl_whenUrlIsMalformed_returnsNull", () => {
		const result = resolveProjectFromUrl("not-a-valid-url");
		assert.equal(result, null);
	});

	test("resolveProjectFromUrl_whenProjectParamHasSpaces_returnsDecodedPath", () => {
		const result = resolveProjectFromUrl(
			"http://localhost:3000/api/boot?project=%2Fhome%2Fmy%20project",
		);
		assert.equal(result, "/home/my project");
	});
});
