import assert from "node:assert/strict";
import { existsSync, mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, it } from "vitest";

import { MemoryStorage } from "./storage.js";

function makeTmpDir(): string {
	return mkdtempSync(join(tmpdir(), "sf-memory-storage-test-"));
}

describe("MemoryStorage node:sqlite persistence", () => {
	let dir: string;

	afterEach(() => {
		if (dir) {
			rmSync(dir, { recursive: true, force: true });
		}
	});

	it("multiple rapid mutations are immediately queryable", async () => {
		dir = makeTmpDir();
		const dbPath = join(dir, "test.db");
		const storage = await MemoryStorage.create(dbPath);

		storage.upsertThreads([
			{
				threadId: "t1",
				filePath: "/a.txt",
				fileSize: 100,
				fileMtime: 1000,
				cwd: "/proj",
			},
		]);
		storage.upsertThreads([
			{
				threadId: "t2",
				filePath: "/b.txt",
				fileSize: 200,
				fileMtime: 2000,
				cwd: "/proj",
			},
		]);
		storage.upsertThreads([
			{
				threadId: "t3",
				filePath: "/c.txt",
				fileSize: 300,
				fileMtime: 3000,
				cwd: "/proj",
			},
		]);

		assert.equal(existsSync(dbPath), true);
		const stats = storage.getStats();
		assert.equal(stats.totalThreads, 3);

		storage.close();
	});

	it("close() releases the database and persisted rows reopen", async () => {
		dir = makeTmpDir();
		const dbPath = join(dir, "test.db");
		const storage = await MemoryStorage.create(dbPath);

		storage.upsertThreads([
			{
				threadId: "t1",
				filePath: "/a.txt",
				fileSize: 100,
				fileMtime: 1000,
				cwd: "/proj",
			},
		]);

		storage.close();

		const reopened = await MemoryStorage.create(dbPath);
		const stats = reopened.getStats();
		assert.equal(
			stats.totalThreads,
			1,
			"Data should be persisted and readable after close",
		);
		reopened.close();
	});
});
