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

/**
 * dev:hot 启动入口。
 *
 * 目标：
 * - 不改动 desktop:hot 的默认行为。
 * - 使用 cargo-watch 自动重编译并重启 mnote-web。
 * - 通过 MNOTE_WEB_DEV_HOT_RELOAD 启用页面端轻量 reload 轮询。
 */

const { spawn } = require("node:child_process");
const fs = require("node:fs");
const path = require("node:path");

const rootDir = path.resolve(__dirname, "..");
const desktopHotPath = path.join(rootDir, "scripts", "desktop-hot.js");

function cargoWatchCommand(env = process.env) {
  const extraArgs = String(env.MNOTE_WEB_DEV_HOT_CARGO_WATCH_ARGS || "").trim();
  const watchArgs = [
    "-w crates/mnote-web/src",
    "-w crates/mnote-web/browser",
    "-w crates/mnote-web/Cargo.toml",
    "-w Cargo.toml",
    "-x \"run -p mnote-web --bin mnote-web\"",
  ];
  if (extraArgs) watchArgs.unshift(extraArgs);
  return `cargo watch ${watchArgs.join(" ")}`;
}

function bindHost(bindAddr) {
  const value = String(bindAddr || "").trim();
  if (!value) return "";
  const ipv6Match = value.match(/^\[([^\]]+)\]:(\d+)$/);
  if (ipv6Match) return ipv6Match[1];
  const lastColon = value.lastIndexOf(":");
  if (lastColon <= 0) return "";
  return value.slice(0, lastColon);
}

function bindPort(bindAddr, fallbackPort) {
  const value = String(bindAddr || "").trim();
  const match = value.match(/:(\d+)$/);
  if (!match) return fallbackPort;
  const port = Number(match[1]);
  return Number.isFinite(port) && port > 0 ? Math.floor(port) : fallbackPort;
}

function devHotBindAddr(env = process.env) {
  const frontendPort = bindPort(env.MNOTE_WEB_BIND, Number(env.FRONTEND_PORT || 3000));
  const host = bindHost(env.MNOTE_WEB_BIND);
  if (!host || host === "127.0.0.1" || host === "localhost" || host === "::1") {
    return `0.0.0.0:${frontendPort}`;
  }
  return String(env.MNOTE_WEB_BIND).trim();
}

function buildDevHotEnv(baseEnv = process.env) {
  return {
    ...baseEnv,
    MNOTE_WEB_DEV_HOT_RELOAD: "1",
    MNOTE_WEB_BIND: devHotBindAddr(baseEnv),
    MNOTE_WEB_CMD: String(baseEnv.MNOTE_WEB_CMD || "").trim() || cargoWatchCommand(baseEnv),
  };
}

function main() {
  if (!fs.existsSync(desktopHotPath)) {
    throw new Error(`缺少 desktop-hot 入口：${desktopHotPath}`);
  }

  const child = spawn(process.execPath, [desktopHotPath], {
    cwd: rootDir,
    env: buildDevHotEnv(process.env),
    stdio: "inherit",
  });

  child.on("exit", (code, signal) => {
    if (signal) {
      process.kill(process.pid, signal);
      return;
    }
    process.exit(code ?? 0);
  });

  child.on("error", (error) => {
    console.error(`[dev-hot] 启动失败：${error.message}`);
    process.exit(1);
  });
}

if (require.main === module) {
  main();
}

module.exports = {
  buildDevHotEnv,
  cargoWatchCommand,
  devHotBindAddr,
};
