#!/usr/bin/env node
/**
 * Run Vite, optionally with the MVFrame DingTalk notify service.
 * 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 children = new Set();
let shuttingDown = false;

function parseArgs(argv) {
  const notifyArgs = [];
  let shouldStartNotify = false;

  for (const arg of argv) {
    if (arg === "-n" || arg === "--notify") {
      shouldStartNotify = true;
      continue;
    }
    notifyArgs.push(arg);
  }

  return { notifyArgs, shouldStartNotify };
}

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

  children.add(child);

  child.on("exit", (code, signal) => {
    children.delete(child);
    if (shuttingDown) return;

    if (optional) {
      if (code !== 0) {
        console.error(`[mvframe-d] ${name} exited with ${signal || code}; vite will keep running`);
      }
      return;
    }

    if (code !== 0) {
      console.error(`[mvframe-d] ${name} exited with ${signal || code}`);
      shutdown(code || 1);
      return;
    }
    shutdown(0);
  });

  child.on("error", (error) => {
    if (optional) {
      children.delete(child);
      console.error(`[mvframe-d] failed to start ${name}: ${error.message}; vite will keep running`);
      return;
    }
    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, shouldStartNotify } = parseArgs(process.argv.slice(2));
const notifyScript = path.join(__dirname, "notify-server.js");
const viteScript = path.join(__dirname, "dev-vite-server.js");

if (shouldStartNotify) {
  spawnChild("notify", process.execPath, [notifyScript, ...notifyArgs], {
    optional: true,
  });
}

spawnChild("vite", process.execPath, [viteScript]);
