#!/usr/bin/env node
import fs from "node:fs/promises";
import path from "node:path";
import os from "node:os";
import { spawnSync } from "node:child_process";

const ROOT = process.cwd();
const SRC = path.join(ROOT, "src");

async function* walk(dir) {
  const entries = await fs.readdir(dir, { withFileTypes: true });
  for (const e of entries) {
    const full = path.join(dir, e.name);
    if (e.isDirectory()) yield* walk(full);
    else yield full;
  }
}

function extractInlineScripts(astroText) {
  // capture <script ... is:inline ...> ... </script>
  const re = /<script\b[^>]*\bis:inline\b[^>]*>([\s\S]*?)<\/script>/gi;
  const out = [];
  let m;
  while ((m = re.exec(astroText))) out.push(m[1] ?? "");
  return out;
}

function checkSyntax(js, label) {
  const tmp = path.join(os.tmpdir(), `inline-js-check-${Date.now()}-${Math.random().toString(16).slice(2)}.mjs`);
  const payload = `// ${label}\n${js}\n`;
  return fs.writeFile(tmp, payload, "utf-8").then(() => {
    const r = spawnSync(process.execPath, ["--check", tmp], { encoding: "utf-8" });
    fs.unlink(tmp).catch(() => {});
    if (r.status !== 0) {
      const msg = (r.stderr || r.stdout || "").trim();
      throw new Error(`${label}\n${msg}`);
    }
  });
}

async function main() {
  const targets = [];
  for await (const f of walk(SRC)) {
    if (f.endsWith(".astro")) targets.push(f);
  }

  let checked = 0;

  for (const file of targets) {
    const txt = await fs.readFile(file, "utf-8");
    const scripts = extractInlineScripts(txt);
    if (!scripts.length) continue;

    for (let i = 0; i < scripts.length; i++) {
      const js = (scripts[i] || "").trim();
      if (!js) continue;
      const label = `${path.relative(ROOT, file)} :: <script is:inline> #${i + 1}`;
      await checkSyntax(js, label);
      checked++;
    }
  }

  console.log(`OK inline-js: scripts checked=${checked}`);
}

main().catch((e) => {
  console.error("❌ inline-js syntax check failed");
  console.error(e?.message || e);
  process.exit(1);
});
