#!/usr/bin/env node

import { existsSync, readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";

const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");

const run = (command, args, options = {}) => {
  const capture = options.capture === true;
  const result = spawnSync(command, args, {
    cwd: repoRoot,
    env: {
      ...process.env,
      MOUI_SKIA_DISABLE_PREBUILD_SKIA:
        process.env.MOUI_SKIA_DISABLE_PREBUILD_SKIA ?? "1",
    },
    stdio: capture ? undefined : "inherit",
    encoding: capture ? "utf8" : undefined,
  });
  if (result.error) {
    console.error(result.error.message);
    process.exit(1);
  }
  if (result.status !== 0) {
    if (capture) {
      if (result.stdout) process.stdout.write(result.stdout);
      if (result.stderr) process.stderr.write(result.stderr);
    }
    process.exit(result.status ?? 1);
  }
  return result.stdout ?? "";
};

const trackedInterfaces = run(
  "git",
  ["ls-files", "-z", "--", ":(glob)**/pkg.generated.mbti"],
  { capture: true },
)
  .split("\0")
  .filter(Boolean)
  .sort();

if (trackedInterfaces.length === 0) {
  console.error("generated interface drift check found no tracked pkg.generated.mbti files");
  process.exit(1);
}

const before = new Map(
  trackedInterfaces.map(path => {
    const absolutePath = resolve(repoRoot, path);
    return [path, existsSync(absolutePath) ? readFileSync(absolutePath) : null];
  }),
);

run("moon", ["info"]);

const changed = trackedInterfaces.filter(path => {
  const absolutePath = resolve(repoRoot, path);
  const previous = before.get(path);
  const current = existsSync(absolutePath) ? readFileSync(absolutePath) : null;
  if (previous === null || current === null) return previous !== current;
  return !previous.equals(current);
});

if (changed.length > 0) {
  console.error("\nGenerated MoonBit interfaces were stale and have been refreshed:");
  for (const path of changed) {
    console.error(`  ${path}`);
  }
  console.error("Review and commit the generated interface changes, then rerun the check.");
  process.exit(1);
}

console.log(`generated interface drift: ok (${trackedInterfaces.length} tracked packages)`);