#!/usr/bin/env node
/**
 * Run Vite and the MVFrame DingTalk notify service together.
 * This mirrors `mvframe-b`: the package owns the command, the host may opt in
 * with `yarn exec mvframe-d` or a local script.
 */
const { spawn } = require("child_process");
const path = require("path");
const fs = require("fs");
const { createRequire } = require("module");

const children = new Set();
let shuttingDown = false;

function spawnChild(name, command, args, options = {}) {
  const child = spawn(command, args, {
    cwd: process.cwd(),
    env: process.env,
    stdio: "inherit",
    shell: false,
    ...options,
  });

  children.add(child);

  child.on("exit", (code, signal) => {
    children.delete(child);
    if (shuttingDown) return;
    if (code !== 0) {
      console.error(`[mvframe-d] ${name} exited with ${signal || code}`);
      shutdown(code || 1);
    }
  });

  child.on("error", (error) => {
    console.error(`[mvframe-d] failed to start ${name}: ${error.message}`);
    shutdown(1);
  });

  return child;
}

function shutdown(code = 0) {
  if (shuttingDown) return;
  shuttingDown = true;
  for (const child of children) {
    if (!child.killed) {
      child.kill("SIGTERM");
    }
  }
  setTimeout(() => process.exit(code), 200);
}

process.on("SIGINT", () => shutdown(0));
process.on("SIGTERM", () => shutdown(0));

const notifyArgs = process.argv.slice(2);
const notifyScript = path.join(__dirname, "notify-server.js");

function resolveViteCli(cwd) {
  let vpkg = "";
  try {
    const projectRequire = createRequire(path.join(cwd, "package.json"));
    vpkg = projectRequire.resolve("vite/package.json");
  } catch {
    // Fall back to node_modules for non-PnP projects.
  }

  if (!vpkg) {
    vpkg = path.join(cwd, "node_modules", "vite", "package.json");
  }

  if (fs.existsSync(vpkg)) {
    const p = require(vpkg);
    const bin = typeof p.bin === "string" ? p.bin : p.bin && p.bin.vite;
    if (bin) {
      const cli = path.join(path.dirname(vpkg), bin);
      if (fs.existsSync(cli)) return cli;
    }
  }
  throw new Error(
    "未在当前项目找到 Vite（请先安装依赖；宿主项目可执行 yarn install 后再运行 mvframe-d）",
  );
}

spawnChild("notify", process.execPath, [notifyScript, ...notifyArgs]);
try {
  const viteEntry = resolveViteCli(process.cwd());
  spawnChild("vite", process.execPath, [viteEntry, "--host", "0.0.0.0"]);
} catch {
  spawnChild("vite", "yarn", ["vite", "--host", "0.0.0.0"]);
}
