/**
 * commands-memory-db.test.mjs — `/memory` database binding coverage.
 *
 * Purpose: prove memory commands bind to the current project SQLite DB and do
 * not reuse an already-open DB from another project in long-lived SF processes.
 */
import assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, test } from "vitest";
import { handleMemory } from "../commands-memory.js";
import { closeDatabase, getDatabase, openDatabase } from "../sf-db.js";

const tmpRoots = [];
const originalCwd = process.cwd();

afterEach(() => {
	process.chdir(originalCwd);
	closeDatabase();
	for (const root of tmpRoots.splice(0)) {
		rmSync(root, { recursive: true, force: true });
	}
});

function makeProject() {
	const root = mkdtempSync(join(tmpdir(), "sf-memory-db-"));
	mkdirSync(join(root, ".sf"), { recursive: true });
	tmpRoots.push(root);
	return root;
}

function makeCtx() {
	const notifications = [];
	return {
		ctx: {
			ui: {
				notify(message, level = "info") {
					notifications.push({ message, level });
				},
			},
		},
		notifications,
	};
}

function countSources(project) {
	closeDatabase();
	assert.equal(openDatabase(join(project, ".sf", "sf.db")), true);
	const db = getDatabase();
	return (
		db?.prepare("SELECT count(*) AS count FROM memory_sources").get()?.count ??
		0
	);
}

test("handleMemory_when_process_switches_projects_opens_current_project_db", async () => {
	const first = makeProject();
	const second = makeProject();

	assert.equal(openDatabase(join(first, ".sf", "sf.db")), true);
	process.chdir(second);

	const { ctx, notifications } = makeCtx();
	await handleMemory('note "second project note"', ctx, {});

	assert.equal(notifications[0]?.level, "info");
	assert.equal(countSources(first), 0);
	assert.equal(countSources(second), 1);
});
