import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import { createServer } from "vite";

const repoRoot = process.cwd();

function normalizePath(value) {
  return value.replace(/\\/g, "/");
}

function findTestFiles(dir) {
  const result = [];
  if (!fs.existsSync(dir)) return result;
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
    if (entry.name === "node_modules" || entry.name === "dist") continue;
    const fullPath = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      result.push(...findTestFiles(fullPath));
      continue;
    }
    if (/\.test\.tsx?$/.test(entry.name)) result.push(fullPath);
  }
  return result.sort();
}

const server = await createServer({
  configFile: path.join(repoRoot, "vite.config.ts"),
  appType: "custom",
  logLevel: "silent",
  server: { middlewareMode: true },
});

try {
  const harness = await server.ssrLoadModule("/src/test/testHarness");
  const testFiles = findTestFiles(path.join(repoRoot, "src"));

  if (testFiles.length === 0) {
    console.error("No test files found.");
    process.exitCode = 1;
  } else {
    console.log(`Running ${testFiles.length} test files`);

    for (const file of testFiles) {
      const modulePath = `/${normalizePath(path.relative(repoRoot, file))}`;
      await server.ssrLoadModule(modulePath);
    }

    const result = await harness.runRegisteredTests();
    console.log(`Unit test result: ${result.passed}/${result.total} passed`);
    if (result.failed > 0) process.exitCode = 1;
  }
} finally {
  await server.close();
}
