import { networkInterfaces } from "node:os";
//#region src/tunnel/tunnel-qr.ts
function trimBase(raw) {
	return raw.trim().replace(/\/+$/, "");
}
/** Non-internal IPv4 addresses on this machine (independent of gateway bind mode). */
function enumerateLanGatewayCandidates(port) {
	const nets = networkInterfaces();
	const seen = /* @__PURE__ */ new Set();
	const out = [];
	for (const [interfaceName, addrs] of Object.entries(nets)) for (const addr of addrs ?? []) {
		if (addr.family !== "IPv4" || addr.internal) continue;
		if (seen.has(addr.address)) continue;
		seen.add(addr.address);
		out.push({
			address: addr.address,
			interfaceName,
			url: trimBase(`http://${addr.address}:${port}`)
		});
	}
	return out;
}
/** First non-internal IPv4 suitable for LAN QR (when gateway listens on 0.0.0.0). */
function resolveLanGatewayUrl(gatewayHost, gatewayPort) {
	const host = gatewayHost.trim().toLowerCase();
	if (host === "127.0.0.1" || host === "localhost" || host === "::1") return null;
	let ip;
	if (host === "0.0.0.0" || host === "::" || host === "") ip = enumerateLanGatewayCandidates(gatewayPort)[0]?.address;
	else if (!host.includes(":")) ip = host;
	if (!ip) return null;
	return trimBase(`http://${ip}:${gatewayPort}`);
}
function buildMobileConnectQrPayload(input) {
	const params = new URLSearchParams();
	params.set("baseUrl", input.publicUrl);
	if (input.lanUrl) params.set("lanUrl", input.lanUrl);
	if (input.pairingSecret) params.set("ps", input.pairingSecret);
	return {
		qrPayload: `xopc://gateway/mobile-connect?${params.toString()}`,
		publicUrl: input.publicUrl,
		lanUrl: input.lanUrl,
		expiresAt: input.expiresAt
	};
}
//#endregion
export { buildMobileConnectQrPayload, enumerateLanGatewayCandidates, resolveLanGatewayUrl };

//# sourceMappingURL=tunnel-qr.js.map