#!/usr/bin/env node
/**
 * 开发启动器：先启动 server (tsx watch)，等它就绪，再启动 client (vite)。
 * Ctrl+C 时同时关闭两个进程。启动前自动清理旧进程。
 */
const { spawn, execSync } = require("child_process");
const http = require("http");

const ROOT = __dirname + "/..";
const SERVER_PORT = 3001;
const CLIENT_PORT = 9527;

function killPort(port) {
  try { execSync(`lsof -ti :${port} | xargs kill -9 2>/dev/null`, { stdio: "ignore" }); } catch {}
}

function startProcess(label, cwd, ...args) {
  const child = spawn(...args, { cwd, stdio: "inherit" });
  child.on("exit", (code) => {
    console.log(`[${label}] exited (${code})`);
    process.exit(code || 0);
  });
  return child;
}

function waitForServer(url, maxRetries = 30) {
  return new Promise((resolve, reject) => {
    let tries = 0;
    function check() {
      http.get(url, (res) => {
        if (res.statusCode === 200) resolve();
        else retry();
      }).on("error", retry);
    }
    function retry() {
      if (++tries >= maxRetries) {
        reject(new Error(`Server did not start within ${maxRetries}s`));
        return;
      }
      setTimeout(check, 1000);
    }
    check();
  });
}

async function main() {
  // 清理旧进程
  killPort(SERVER_PORT);
  killPort(CLIENT_PORT);

  console.log("[dev] Starting server...");
  startProcess("server", ROOT, "npm", ["run", "dev:server"]);

  console.log("[dev] Waiting for server...");
  await waitForServer(`http://localhost:${SERVER_PORT}/api/v1/templates`);
  console.log("[dev] Server ready.");

  console.log("[dev] Starting client...");
  startProcess("client", ROOT, "npm", ["run", "dev:client"]);
}

main().catch((err) => {
  console.error(err.message);
  process.exit(1);
});
