#!/usr/bin/env node
"use strict";

const fs = require("fs/promises");
const path = require("path");
const { spawnSync } = require("child_process");

const REPO_ROOT = path.resolve(__dirname, "..", "..");
const RUST_ROOT = path.join(REPO_ROOT, "rust");
const CRATE_ROOT = path.join(RUST_ROOT, "crates", "tree-shell-runtime-wasm");
const GENERATED_ROOT = path.join(CRATE_ROOT, "generated");
const TOOLCHAIN = "1.89.0-x86_64-unknown-linux-gnu";
const TARGET = "wasm32-unknown-unknown";
const OUT_NAME = "mnote-tree-shell-runtime";
const MANIFEST_PATH = path.join(CRATE_ROOT, "Cargo.toml");
const WASM_PATH = path.join(
  RUST_ROOT,
  "target",
  TARGET,
  "debug",
  "tree_shell_runtime_wasm.wasm",
);
const ENTRY_PATH = path.join(GENERATED_ROOT, `${OUT_NAME}.js`);
const OUTPUT_WASM_PATH = path.join(GENERATED_ROOT, `${OUT_NAME}_bg.wasm`);
const GITIGNORE_PATH = path.join(GENERATED_ROOT, ".gitignore");

function run(command, args, options = {}) {
  const result = spawnSync(command, args, {
    cwd: options.cwd ?? REPO_ROOT,
    env: process.env,
    encoding: "utf8",
    stdio: "pipe",
  });

  if (result.status === 0) {
    return result;
  }

  const stdout = (result.stdout || "").trim();
  const stderr = (result.stderr || "").trim();
  const details = [stdout, stderr].filter(Boolean).join("\n");
  throw new Error(
    [`命令失败：${command} ${args.join(" ")}`, details].filter(Boolean).join("\n"),
  );
}

async function ensureGeneratedDir() {
  await fs.rm(GENERATED_ROOT, { recursive: true, force: true });
  await fs.mkdir(GENERATED_ROOT, { recursive: true });
  await fs.writeFile(GITIGNORE_PATH, "*\n!.gitignore\n", "utf8");
}

async function verifyOutput() {
  const entrySource = await fs.readFile(ENTRY_PATH, "utf8");
  await fs.access(OUTPUT_WASM_PATH);

  if (!entrySource.includes("export function reduceTreeShellRuntime")) {
    throw new Error("tree shell runtime js glue 缺少 reduceTreeShellRuntime 导出");
  }
}

async function buildTreeShellRuntime() {
  // 说明：tree shell iframe 主链直接加载固定 wasm/js 产物，因此在 Next 启动前先生成正式 artifact。
  run("rustup", ["target", "add", TARGET, "--toolchain", TOOLCHAIN], { cwd: RUST_ROOT });
  run(
    "cargo",
    [
      `+${TOOLCHAIN}`,
      "build",
      "--manifest-path",
      MANIFEST_PATH,
      "--package",
      "tree-shell-runtime-wasm",
      "--lib",
      "--target",
      TARGET,
      "--locked",
    ],
    { cwd: RUST_ROOT },
  );

  await ensureGeneratedDir();

  run(
    "wasm-bindgen",
    [
      WASM_PATH,
      "--target",
      "web",
      "--out-dir",
      GENERATED_ROOT,
      "--out-name",
      OUT_NAME,
    ],
    { cwd: RUST_ROOT },
  );

  await verifyOutput();

  return {
    generatedRoot: GENERATED_ROOT,
    entryPath: ENTRY_PATH,
    wasmPath: OUTPUT_WASM_PATH,
  };
}

module.exports = {
  buildTreeShellRuntime,
  GENERATED_ROOT,
  OUT_NAME,
};

if (require.main === module) {
  buildTreeShellRuntime()
    .then(({ generatedRoot }) => {
      process.stdout.write(`tree shell runtime 已生成：${generatedRoot}\n`);
    })
    .catch((error) => {
      process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
      process.exit(1);
    });
}
