/**
 * Vitest configuration for singularity-forge.
 *
 * Runs tests directly from TypeScript source — no esbuild pre-compilation needed.
 * Vitest handles TypeScript transformation via esbuild (bundled, not separate process).
 *
 * Coverage uses @vitest/coverage-v8 (same engine as c8, but integrated).
 *
 * Usage:
 *   npx vitest run              # run all tests once
 *   npx vitest                  # watch mode
 *   npx vitest run --changed    # only tests affected by recent changes
 */

import { existsSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig } from "vitest/config";

const __dirname = import.meta.dirname;

export default defineConfig({
	plugins: [
		{
			name: "sf-resource-js-extension-resolver",
			enforce: "pre",
			resolveId(source, importer) {
				if (
					!source.endsWith(".ts") ||
					!source.includes("resources/extensions")
				) {
					return null;
				}
				const importerPath = importer?.startsWith("file://")
					? fileURLToPath(importer)
					: importer;
				const tsPath = source.startsWith("/")
					? resolve(__dirname, source.slice(1))
					: importerPath
						? resolve(dirname(importerPath), source)
						: resolve(__dirname, source);
				const jsPath = tsPath.replace(/\.ts$/, ".js");
				if (!existsSync(tsPath) && existsSync(jsPath)) return jsPath;
				return null;
			},
		},
	],
	// ── TypeScript / module resolution ─────────────────────────────────────────
	// Vitest uses esbuild for TS transform (fast, bundled). We still set up
	// NodeNext module resolution and path aliases to match the project's tsconfig.
	resolve: {
		alias: {
			"@singularity-forge/coding-agent": resolve(
				__dirname,
				"packages/coding-agent/src/index.ts",
			),
			"@singularity-forge/ai/oauth": resolve(
				__dirname,
				"packages/ai/src/utils/oauth/index.ts",
			),
			"@singularity-forge/ai/bedrock-provider": resolve(
				__dirname,
				"packages/ai/src/bedrock-provider.ts",
			),
			"@singularity-forge/ai": resolve(__dirname, "packages/ai/src/index.ts"),
			"@singularity-forge/agent-core": resolve(
				__dirname,
				"packages/agent-core/src/index.ts",
			),
			"@singularity-forge/tui/fuzzy": resolve(
				__dirname,
				"packages/tui/src/fuzzy.ts",
			),
			"@singularity-forge/tui": resolve(__dirname, "packages/tui/src/index.ts"),
			"@singularity-forge/native/ast": resolve(
				__dirname,
				"packages/native/src/ast/index.ts",
			),
			"@singularity-forge/native/clipboard": resolve(
				__dirname,
				"packages/native/src/clipboard/index.ts",
			),
			"@singularity-forge/native/diff": resolve(
				__dirname,
				"packages/native/src/diff/index.ts",
			),
			"@singularity-forge/native/edit": resolve(
				__dirname,
				"packages/native/src/edit/index.ts",
			),
			"@singularity-forge/native/fd": resolve(
				__dirname,
				"packages/native/src/fd/index.ts",
			),
			"@singularity-forge/native/forge-parser": resolve(
				__dirname,
				"packages/native/src/forge-parser/index.ts",
			),
			"@singularity-forge/native/glob": resolve(
				__dirname,
				"packages/native/src/glob/index.ts",
			),
			"@singularity-forge/native/grep": resolve(
				__dirname,
				"packages/native/src/grep/index.ts",
			),
			"@singularity-forge/native/highlight": resolve(
				__dirname,
				"packages/native/src/highlight/index.ts",
			),
			"@singularity-forge/native/html": resolve(
				__dirname,
				"packages/native/src/html/index.ts",
			),
			"@singularity-forge/native/image": resolve(
				__dirname,
				"packages/native/src/image/index.ts",
			),
			"@singularity-forge/native/json-parse": resolve(
				__dirname,
				"packages/native/src/json-parse/index.ts",
			),
			"@singularity-forge/native/ps": resolve(
				__dirname,
				"packages/native/src/ps/index.ts",
			),
			"@singularity-forge/native/stream-process": resolve(
				__dirname,
				"packages/native/src/stream-process/index.ts",
			),
			"@singularity-forge/native/text": resolve(
				__dirname,
				"packages/native/src/text/index.ts",
			),
			"@singularity-forge/native/truncate": resolve(
				__dirname,
				"packages/native/src/truncate/index.ts",
			),
			"@singularity-forge/native/ttsr": resolve(
				__dirname,
				"packages/native/src/ttsr/index.ts",
			),
			"@singularity-forge/native/xxhash": resolve(
				__dirname,
				"packages/native/src/xxhash/index.ts",
			),
			"@singularity-forge/native": resolve(
				__dirname,
				"packages/native/src/index.ts",
			),
			"@singularity-forge/rpc-client": resolve(
				__dirname,
				"packages/rpc-client/src/index.ts",
			),
		},
	},
	test: {
		// ── File patterns ─────────────────────────────────────────────────────────
		// Files without vitest imports (standalone test scripts that run assertions
		// directly at module load time — these are skipped by the old node --test
		// runner and must be excluded here too to avoid "No test suite found" errors.
		include: [
			"src/tests/**/*.test.ts",
			"src/tests/**/*.test.mjs",
			"src/resources/extensions/sf/tests/**/*.test.ts",
			"src/resources/extensions/sf/tests/**/*.test.mjs",
			"src/resources/extensions/sf/learning/*.test.mjs",
			"src/resources/extensions/sf-permissions/tests/**/*.test.ts",
			"src/resources/extensions/shared/tests/**/*.test.ts",
			"src/resources/extensions/claude-code-cli/tests/**/*.test.ts",
			"src/resources/extensions/github-sync/tests/**/*.test.ts",
			"src/resources/extensions/universal-config/tests/**/*.test.ts",
			"src/resources/extensions/voice/tests/**/*.test.ts",
			"src/resources/extensions/mcp-client/tests/**/*.test.ts",
			"src/resources/extensions/async-jobs/*.test.ts",
			"src/resources/extensions/browser-tools/tests/*.test.mjs",
			"packages/coding-agent/src/**/*.test.ts",
			"packages/ai/src/**/*.test.ts",
			"packages/agent-core/src/**/*.test.ts",
			"packages/tui/src/**/*.test.ts",
			"packages/daemon/src/**/*.test.ts",
			"packages/rpc-client/src/**/*.test.ts",
			"packages/native/src/**/*.test.mjs",
			"web/lib/**/*.test.ts",
			"scripts/*.test.mjs",
		],

		// ── Timeouts ──────────────────────────────────────────────────────────────
		// Cold vitest+esbuild module-graph import takes 16-25s on this repo
		// (dynamic imports of captures.js and friends). 30s tests-timeout was
		// racing the import phase, producing spurious 30s failures across
		// dev-engine, ensure-db-open, workflow-tools, sf-tools, verification-gate,
		// etc. 60s gives the import time to settle without losing real-bug signal.
		testTimeout: 60_000,
		hookTimeout: 60_000,

		// ── Pool: forks = one Node process per test file (best for Node.js tests) ─
		pool: "forks",
		// Single worker in CI; parallel in dev for speed
		singleFork: process.env.CI === "true",

		// ── Coverage ──────────────────────────────────────────────────────────────
		coverage: {
			provider: "v8",
			reporter: ["text", "lcov"],
			exclude: [
				"src/resources/extensions/sf/tests/**",
				"src/tests/**",
				"scripts/**",
				"rust-engine/**",
				"node_modules/**",
				"dist/**",
				"dist-test/**",
				"web/**",
			],
			thresholds: {
				statements: 40,
				lines: 40,
				branches: 20,
				functions: 20,
				"src/resources/extensions/sf/auto/**": {
					statements: 60,
					lines: 60,
					branches: 40,
					functions: 60,
				},
				"src/resources/extensions/sf/uok/**": {
					statements: 60,
					lines: 60,
					branches: 40,
					functions: 60,
				},
			},
		},
	},
});
