import fs from "node:fs/promises";
import path from "node:path";
import { execFileSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import { buildContentBundle } from "./build-content-bundle.mjs";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const rootDir = path.resolve(__dirname, "..");

await buildContentBundle();
await validateManifest();
await checkSyntax();
runTests();

async function validateManifest() {
  const manifestPath = path.join(rootDir, "manifest.json");
  JSON.parse(await fs.readFile(manifestPath, "utf8"));
}

async function checkSyntax() {
  const files = await collectFiles(rootDir);
  const jsFiles = files.filter((file) => file.endsWith(".js") || file.endsWith(".mjs"));
  for (const file of jsFiles) {
    execFileSync("node", ["--check", file], { stdio: "pipe" });
  }
}

async function collectFiles(dir) {
  const entries = await fs.readdir(dir, { withFileTypes: true });
  const results = [];
  for (const entry of entries) {
    if (["dist", ".git", "node_modules"].includes(entry.name)) {
      continue;
    }
    const fullPath = path.join(dir, entry.name);
    if (entry.isDirectory()) {
      results.push(...(await collectFiles(fullPath)));
    } else {
      results.push(fullPath);
    }
  }
  return results;
}

function runTests() {
  const testsDir = path.join(rootDir, "tests");
  let testFiles = [];

  try {
    testFiles = execFileSync("find", [testsDir, "-name", "*.test.mjs", "-type", "f"], {
      cwd: rootDir,
      encoding: "utf8",
      stdio: ["ignore", "pipe", "ignore"]
    })
      .split("\n")
      .map((item) => item.trim())
      .filter(Boolean)
      .sort();
  } catch (error) {
    testFiles = [];
  }

  if (!testFiles.length) {
    return;
  }

  execFileSync("node", ["--test", ...testFiles], {
    cwd: rootDir,
    stdio: "inherit"
  });
}
