/**
 * sqlite-unavailable-gate.test.ts — #2419
 *
 * When the SQLite provider fails to open, bootstrapAutoSession must
 * refuse to start auto-mode. Otherwise sf_task_complete returns
 * "db_unavailable", artifact retry re-dispatches the same task, and
 * the session loops forever.
 */

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, it } from "vitest";

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

describe("#2419: SQLite unavailable gate in auto-start.ts", () => {
	it("has a DB lifecycle section", () => {
		const dbLifecycleIdx = src.indexOf("DB lifecycle");
		assert.ok(dbLifecycleIdx > 0);
	});

	it("DB lifecycle section still checks for unavailable DB state", () => {
		const afterDbLifecycle = src.slice(src.indexOf("DB lifecycle"));
		assert.ok(afterDbLifecycle.includes("!isDbAvailable()"));
	});

	it("has a hard abort gate when sf.db exists but SQLite is still unavailable", () => {
		const afterDbLifecycle = src.slice(src.indexOf("DB lifecycle"));

		const gateMatch = afterDbLifecycle.match(
			/if\s*\(existsSync\(sfDbPath\)\s*&&\s*!isDbAvailable\(\)\)\s*\{[\s\S]*?releaseLockAndReturn\(\);[\s\S]*?\}/,
		);

		assert.ok(!!gateMatch);
	});

	it("DB availability gate calls releaseLockAndReturn() to abort bootstrap", () => {
		const afterDbLifecycle = src.slice(src.indexOf("DB lifecycle"));

		const gateMatch = afterDbLifecycle.match(
			/if\s*\(existsSync\(sfDbPath\)\s*&&\s*!isDbAvailable\(\)\)\s*\{[\s\S]*?releaseLockAndReturn\(\);[\s\S]*?\}/,
		);

		assert.ok(gateMatch && gateMatch[0].includes("releaseLockAndReturn"));
	});

	it("DB availability gate includes user-facing error message about the database", () => {
		const afterDbLifecycle = src.slice(src.indexOf("DB lifecycle"));

		const gateMatch = afterDbLifecycle.match(
			/if\s*\(existsSync\(sfDbPath\)\s*&&\s*!isDbAvailable\(\)\)\s*\{[\s\S]*?releaseLockAndReturn\(\);[\s\S]*?\}/,
		);

		assert.ok(
			gateMatch && /database|sqlite|db.*unavailable/i.test(gateMatch[0]),
		);
	});
});
