import { r as __exportAll } from "./chunk-D_gEzPfs.js";
import { u as resolveGatewayPort } from "./paths-VdmjGGyc.js";
import { o as loadConfig, u as writeConfigFile } from "./config-CJCyYQfd.js";
import { h as resolveControlUiLinks, m as randomToken, p as probeGatewayReachable, v as waitForGatewayReachable } from "./onboard-helpers-BfbPZ2qa.js";
import { i as buildGatewayInstallPlan, t as DEFAULT_GATEWAY_DAEMON_RUNTIME } from "./daemon-runtime-DUaeQ1rH.js";
import process from "node:process";
import { spawn } from "node:child_process";

//#region src/commands/ensure-local-gateway.ts
/**
* @module commands/ensure-local-gateway
*
* Make sure a local gateway is actually RUNNING so the TUI/koi can connect.
*
* The TUI only ever *connects* — it never starts a gateway. After an admin
* unlock (or any keyed local setup) the koi would otherwise fail with
* "gateway not connected". This helper guarantees a reachable local gateway:
* it ensures the gateway config (local mode + token), and if nothing is
* listening it spawns the gateway detached — reusing the exact program
* arguments the daemon installer computes, and inheriting the current env
* (so SKYKOI_STATE_DIR / port overrides are honoured). Detached + unref'd so
* it outlives the CLI process and keeps serving the koi.
*/
var ensure_local_gateway_exports = /* @__PURE__ */ __exportAll({ ensureLocalGatewayRunning: () => ensureLocalGatewayRunning });
async function ensureLocalGatewayRunning() {
	const config = loadConfig();
	const gateway = config.gateway ??= {};
	if (gateway.mode !== "local") gateway.mode = "local";
	if (!gateway.bind) gateway.bind = "loopback";
	const auth = gateway.auth ??= {};
	if (!auth.mode) auth.mode = "token";
	if (!auth.token || !auth.token.trim()) auth.token = randomToken();
	const token = auth.token;
	await writeConfigFile(config);
	const port = resolveGatewayPort(config);
	const { wsUrl } = resolveControlUiLinks({
		bind: "loopback",
		port
	});
	if ((await probeGatewayReachable({
		url: wsUrl,
		token
	})).ok) return {
		ok: true,
		wsUrl,
		token,
		started: false
	};
	let plan;
	try {
		plan = await buildGatewayInstallPlan({
			env: process.env,
			port,
			token,
			runtime: DEFAULT_GATEWAY_DAEMON_RUNTIME,
			config
		});
	} catch (err) {
		return {
			ok: false,
			error: `Could not prepare the gateway (${errMsg(err)})`
		};
	}
	const [cmd, ...args] = plan.programArguments;
	if (!cmd) return {
		ok: false,
		error: "Gateway program arguments were unavailable"
	};
	try {
		spawn(cmd, args, {
			cwd: plan.workingDirectory,
			env: {
				...process.env,
				...plan.environment
			},
			detached: true,
			stdio: "ignore"
		}).unref();
	} catch (err) {
		return {
			ok: false,
			error: `Could not start the gateway (${errMsg(err)})`
		};
	}
	const reachable = await waitForGatewayReachable({
		url: wsUrl,
		token,
		deadlineMs: 25e3
	});
	if (!reachable.ok) return {
		ok: false,
		error: `Gateway started but did not become reachable${reachable.detail ? ` (${reachable.detail})` : ""}`
	};
	return {
		ok: true,
		wsUrl,
		token,
		started: true
	};
}
function errMsg(err) {
	return err?.message ?? String(err);
}

//#endregion
export { ensure_local_gateway_exports as n, ensureLocalGatewayRunning as t };