/**
 * cold-resume-db-reopen.test.ts — Regression test for #2940.
 *
 * Validates that the paused-session resume path in auto.ts opens the project
 * database before calling rebuildState() / deriveState(), matching the fresh
 * bootstrap path in auto-start.ts.
 */

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

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

describe("#2940: resume path refreshes resources and opens DB before rebuildState/deriveState", () => {
	it("auto.ts has the paused-session resume block", () => {
		const resumeSectionStart = autoSrc.indexOf(
			"if (s.paused) {",
			autoSrc.indexOf("// If resuming from paused state"),
		);
		assert.ok(resumeSectionStart > 0);
	});

	it("resume block reaches the dispatch loop", () => {
		const resumeSectionStart = autoSrc.indexOf(
			"if (s.paused) {",
			autoSrc.indexOf("// If resuming from paused state"),
		);

		const resumeSectionEndCandidates = [
			autoSrc.indexOf("await runAutoLoopWithUok(", resumeSectionStart),
			autoSrc.indexOf("await autoLoop(", resumeSectionStart),
		].filter((idx) => idx > resumeSectionStart);

		const resumeSectionEnd =
			resumeSectionEndCandidates.length > 0
				? Math.min(...resumeSectionEndCandidates)
				: -1;

		assert.ok(resumeSectionEnd > resumeSectionStart);
	});

	it("resume block calls rebuildState", () => {
		const resumeSectionStart = autoSrc.indexOf(
			"if (s.paused) {",
			autoSrc.indexOf("// If resuming from paused state"),
		);
		const resumeSectionEndCandidates = [
			autoSrc.indexOf("await runAutoLoopWithUok(", resumeSectionStart),
			autoSrc.indexOf("await autoLoop(", resumeSectionStart),
		].filter((idx) => idx > resumeSectionStart);
		const resumeSectionEnd =
			resumeSectionEndCandidates.length > 0
				? Math.min(...resumeSectionEndCandidates)
				: -1;

		const resumeSection = autoSrc.slice(resumeSectionStart, resumeSectionEnd);
		const rebuildIdx = resumeSection.indexOf("rebuildState(");
		assert.ok(rebuildIdx > 0);
	});

	it("resume block calls deriveState", () => {
		const resumeSectionStart = autoSrc.indexOf(
			"if (s.paused) {",
			autoSrc.indexOf("// If resuming from paused state"),
		);
		const resumeSectionEndCandidates = [
			autoSrc.indexOf("await runAutoLoopWithUok(", resumeSectionStart),
			autoSrc.indexOf("await autoLoop(", resumeSectionStart),
		].filter((idx) => idx > resumeSectionStart);
		const resumeSectionEnd =
			resumeSectionEndCandidates.length > 0
				? Math.min(...resumeSectionEndCandidates)
				: -1;

		const resumeSection = autoSrc.slice(resumeSectionStart, resumeSectionEnd);
		const deriveIdx = resumeSection.indexOf("deriveState(");
		assert.ok(deriveIdx > 0);
	});

	it("resume path must refresh managed resources before rebuildState/deriveState", () => {
		const resumeSectionStart = autoSrc.indexOf(
			"if (s.paused) {",
			autoSrc.indexOf("// If resuming from paused state"),
		);
		const resumeSectionEndCandidates = [
			autoSrc.indexOf("await runAutoLoopWithUok(", resumeSectionStart),
			autoSrc.indexOf("await autoLoop(", resumeSectionStart),
		].filter((idx) => idx > resumeSectionStart);
		const resumeSectionEnd =
			resumeSectionEndCandidates.length > 0
				? Math.min(...resumeSectionEndCandidates)
				: -1;

		const resumeSection = autoSrc.slice(resumeSectionStart, resumeSectionEnd);
		const preDeriveSection = resumeSection.slice(0, resumeSection.indexOf("rebuildState("));

		assert.ok(preDeriveSection.includes("initResources("));
	});

	it("resume path must open DB before rebuildState/deriveState", () => {
		const resumeSectionStart = autoSrc.indexOf(
			"if (s.paused) {",
			autoSrc.indexOf("// If resuming from paused state"),
		);
		const resumeSectionEndCandidates = [
			autoSrc.indexOf("await runAutoLoopWithUok(", resumeSectionStart),
			autoSrc.indexOf("await autoLoop(", resumeSectionStart),
		].filter((idx) => idx > resumeSectionStart);
		const resumeSectionEnd =
			resumeSectionEndCandidates.length > 0
				? Math.min(...resumeSectionEndCandidates)
				: -1;

		const resumeSection = autoSrc.slice(resumeSectionStart, resumeSectionEnd);
		const preDeriveSection = resumeSection.slice(0, resumeSection.indexOf("rebuildState("));

		const dbOpenPatterns = [
			"openProjectDbIfPresent(",
			"openDatabase(",
			"ensureDbOpen(",
		];

		const hasDbOpen = dbOpenPatterns.some((pat) =>
			preDeriveSection.includes(pat)
		);
		assert.ok(hasDbOpen);
	});
});
