import { getManagerStatus, readDaemonLogs, restartDaemon, startDaemon, stopDaemon } from "./daemon-service.js";
import { startManagerServer } from "./index.js";
import { runTrayApp } from "./tray.js";
import { spawnHidden } from "./spawn-hidden.js";
import path from "node:path";
import { fileURLToPath } from "node:url";
const DEFAULT_DAEMON_LISTEN = "0.0.0.0:6769";
export function printHelp() {
    process.stdout.write(`Kong Link server

Usage:
  kong-link [command] [options]

Commands:
  start       Start the daemon in the background
  stop        Stop the daemon
  restart     Restart the daemon
  status      Show daemon status (JSON with --json)
  logs        Show recent daemon logs
  tray        System tray icon (Start/Stop/Status — like Tailscale)
  ui          Web manager UI (default http://127.0.0.1:6770)
  help        Show this help

Options:
  --background    Start detached in the background (default for "start")
  --foreground    Attach logs to this terminal
  --tray          Also open system tray after start
  --json          JSON output (status command)
  --open          Open the manager UI in your browser (ui command)
  --tail <n>      Log lines to show (logs command, default 50)

Environment:
  PASEO_LISTEN           Daemon listen address (default ${DEFAULT_DAEMON_LISTEN})
  PASEO_MANAGER_LISTEN   Manager UI listen address (default 127.0.0.1:6770)
  PASEO_HOME             Config/state directory (default ~/.paseo)

Examples:
  kong-link                  Start daemon in foreground (logs attached)
  kong-link start            Start daemon in background
  kong-link tray             Tray icon to manage server
  kong-link status
`);
}
function parseFlag(args, name) {
    return args.includes(name);
}
function parseOption(args, name) {
    const index = args.indexOf(name);
    if (index === -1) {
        return undefined;
    }
    return args[index + 1];
}
function ensureDaemonListen() {
    if (!process.env.PASEO_LISTEN?.trim()) {
        process.env.PASEO_LISTEN = DEFAULT_DAEMON_LISTEN;
    }
}
async function cmdStatus(args) {
    const status = await getManagerStatus();
    if (parseFlag(args, "--json")) {
        process.stdout.write(`${JSON.stringify(status, null, 2)}\n`);
        return 0;
    }
    const daemon = status.daemon;
    const local = daemon?.localDaemon ?? "unknown";
    const health = status.health.ok ? "healthy" : "unreachable";
    process.stdout.write(`Kong Link daemon: ${local} (${health})\n`);
    if (daemon?.listen) {
        process.stdout.write(`Listen: ${daemon.listen}\n`);
    }
    if (daemon?.pid != null) {
        process.stdout.write(`PID: ${daemon.pid}\n`);
    }
    if (status.tailscale.ipv4) {
        const port = (daemon?.listen ?? process.env.PASEO_LISTEN ?? DEFAULT_DAEMON_LISTEN).split(":").pop();
        process.stdout.write(`Tailscale: http://${status.tailscale.ipv4}:${port}\n`);
    }
    if (status.health.url) {
        process.stdout.write(`Health: ${status.health.url}\n`);
    }
    process.stdout.write(`Tray: run "kong-link tray"\n`);
    if (daemon?.note || status.error) {
        process.stderr.write(`Note: ${daemon?.note ?? status.error}\n`);
    }
    return status.health.ok ? 0 : 1;
}
async function cmdLogs(args) {
    const tailRaw = parseOption(args, "--tail");
    const tail = tailRaw ? Number.parseInt(tailRaw, 10) : 50;
    const safeTail = Number.isFinite(tail) ? Math.min(Math.max(tail, 10), 2000) : 50;
    const { logPath, contents } = readDaemonLogs(safeTail);
    process.stdout.write(`# ${logPath}\n`);
    process.stdout.write(contents ? `${contents}\n` : "(empty)\n");
    return 0;
}
async function cmdStart(args) {
    ensureDaemonListen();
    const result = await startDaemon();
    process.stdout.write(`${result.message}\n`);
    if (parseFlag(args, "--tray")) {
        await spawnTrayDetached();
        process.stdout.write("Kong Link tray started.\n");
    }
    return 0;
}
async function cmdStop() {
    const result = await stopDaemon();
    process.stdout.write(`${result.message}\n`);
    return 0;
}
async function cmdRestart() {
    ensureDaemonListen();
    const result = await restartDaemon();
    process.stdout.write(`${result.message}\n`);
    return 0;
}
async function spawnTrayDetached() {
    const cliPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "cli.js");
    const child = spawnHidden(process.execPath, [cliPath, "tray"], { env: process.env });
    child.unref();
}
async function cmdTray() {
    return runTrayApp();
}
async function cmdUi(args) {
    const listen = process.env.PASEO_MANAGER_LISTEN?.trim() || "127.0.0.1:6770";
    await startManagerServer(listen);
    const url = listen.startsWith("http") ? listen : `http://${listen}`;
    process.stdout.write(`Kong Link manager: ${url}\n`);
    if (parseFlag(args, "--open")) {
        await openBrowser(url);
    }
    return 0;
}
async function openBrowser(url) {
    const { spawn } = await import("node:child_process");
    const platform = process.platform;
    if (platform === "win32") {
        spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore", windowsHide: true }).unref();
        return;
    }
    if (platform === "darwin") {
        spawn("open", [url], { detached: true, stdio: "ignore" }).unref();
        return;
    }
    spawn("xdg-open", [url], { detached: true, stdio: "ignore" }).unref();
}
async function runForegroundStart() {
    const { spawn } = await import("node:child_process");
    const { resolveSupervisorInvocation } = await import("./resolve-supervisor.js");
    ensureDaemonListen();
    const { command, args: supervisorArgs } = resolveSupervisorInvocation();
    const WINDOWS_CREATE_NO_WINDOW = 0x08000000;
    const child = spawn(command, supervisorArgs, {
        stdio: "inherit",
        env: process.env,
        windowsHide: true,
        ...(process.platform === "win32" ? { creationFlags: WINDOWS_CREATE_NO_WINDOW } : {}),
    });
    return new Promise((resolve) => {
        child.on("error", (error) => {
            process.stderr.write(`${error.message}\n`);
            resolve(1);
        });
        child.on("exit", (code, signal) => {
            resolve(signal ? 1 : (code ?? 1));
        });
    });
}
export async function runCommand(argv) {
    const args = argv.filter((arg) => arg !== "--");
    const positional = args.filter((arg) => !arg.startsWith("-"));
    if (positional.length === 0) {
        ensureDaemonListen();
        if (parseFlag(args, "--background")) {
            return cmdStart(args);
        }
        return runForegroundStart();
    }
    const command = positional[0];
    const commandArgs = args.filter((arg) => arg !== command);
    switch (command) {
        case "help":
        case "-h":
        case "--help":
            printHelp();
            return 0;
        case "status":
            return cmdStatus(commandArgs);
        case "logs":
            return cmdLogs(commandArgs);
        case "start":
            if (parseFlag(commandArgs, "--foreground")) {
                return runForegroundStart();
            }
            return cmdStart(commandArgs);
        case "stop":
            return cmdStop();
        case "restart":
            return cmdRestart();
        case "tray":
            return cmdTray();
        case "ui":
        case "manage":
            return cmdUi(commandArgs);
        default:
            process.stderr.write(`Unknown command: ${command}\n\n`);
            printHelp();
            return 1;
    }
}
