import { lstat, readFile, readdir } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { verifyJavaPack } from "./java-engine-pack.mjs";
import { verifyPcre2Pack } from "./pcre2-engine-pack.mjs";
import { verifyPythonPack } from "./python-engine-pack.mjs";

const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const arguments_ = process.argv.slice(2);

if (arguments_.length > 0) {
  const verifiers = new Map([
    ["--java-pack", verifyJavaPack],
    ["--pcre2-pack", verifyPcre2Pack],
    ["--python-pack", verifyPythonPack],
  ]);
  const verifier = verifiers.get(arguments_[0]);
  if (arguments_.length !== 2 || !verifier) {
    throw new Error(
      "Usage: node scripts/verify-engine-assets.mjs [--java-pack|--pcre2-pack|--python-pack PATH]",
    );
  }
  const pack = path.resolve(root, arguments_[1]);
  const metadata = await verifier(pack, root);
  console.log(`Verified staged ${metadata.engineVersion} engine pack.`);
  process.exit(0);
}

const engineDirectory = path.join(root, "dist", "engines");
const details = await lstat(engineDirectory);
if (details.isSymbolicLink() || !details.isDirectory()) {
  throw new Error("dist/engines must be a real directory.");
}

const entries = (await readdir(engineDirectory, { withFileTypes: true })).sort(
  (left, right) =>
    left.name < right.name ? -1 : left.name > right.name ? 1 : 0,
);
if (
  entries.length !== 4 ||
  !entries[0]?.isFile() ||
  entries[0].name !== "README.md" ||
  !entries[1]?.isDirectory() ||
  entries[1].name !== "java" ||
  !entries[2]?.isDirectory() ||
  entries[2].name !== "pcre2" ||
  !entries[3]?.isDirectory() ||
  entries[3].name !== "python"
) {
  throw new Error(
    "The production build must contain only README.md and the declared Java, PCRE2 and Python packs.",
  );
}

const notice = await readFile(path.join(engineDirectory, "README.md"), "utf8");
if (
  !notice.includes("native `RegExp`") ||
  !notice.includes("PCRE2 10.47") ||
  !notice.includes("Pyodide 314.0.3") ||
  !notice.includes("TeaVM 0.15.0")
) {
  throw new Error("The engine asset notice does not describe this release.");
}
await verifyPcre2Pack(path.join(engineDirectory, "pcre2"), root);
await verifyPythonPack(path.join(engineDirectory, "python"), root);
await verifyJavaPack(path.join(engineDirectory, "java"), root);

console.log(
  "Verified native ECMAScript and bundled PCRE2, CPython/Pyodide and TeaVM Java engine assets.",
);
