import { isLoopbackHost } from "../gateway/host.js";
import { resolveGatewayBindMode } from "../config/gateway-bind.js";
import { resolveGatewayListenPlan } from "../gateway/listen.js";
//#region src/remote-access/exposure-guards.ts
function collectExposureConflicts(cfg) {
	const conflicts = [];
	const tailscaleMode = cfg.gateway?.tailscale?.mode ?? "off";
	const bindMode = resolveGatewayBindMode(cfg);
	if (tailscaleMode !== "off" && bindMode !== "loopback") conflicts.push({
		code: "tailscale_non_loopback_bind",
		message: `gateway.tailscale.mode=${tailscaleMode} requires gateway.bind=loopback`
	});
	if (tailscaleMode === "funnel" && cfg.gateway?.auth?.mode !== "password") conflicts.push({
		code: "funnel_without_password",
		message: "gateway.tailscale.mode=funnel requires gateway.auth.mode=password"
	});
	if (tailscaleMode !== "off" && cfg.tunnel?.autoStart === true) conflicts.push({
		code: "tailscale_frp_autostart_conflict",
		message: "tunnel.autoStart cannot be enabled while Tailscale exposure is active"
	});
	return conflicts;
}
function assertExposureConfig(cfg) {
	const conflicts = collectExposureConflicts(cfg);
	if (conflicts.length > 0) throw new Error(conflicts.map((c) => c.message).join("; "));
}
function resolveEffectiveTailscaleMode(cfg, override) {
	if (override) return override;
	return cfg.gateway?.tailscale?.mode ?? "off";
}
function isGatewayTlsEnabled(cfg) {
	return cfg.gateway?.tls?.enabled === true || cfg.tunnel?.enabled === true || (cfg.gateway?.tailscale?.mode ?? "off") !== "off";
}
function isRemoteGatewayInsecure(cfg) {
	if (cfg.gateway?.mode !== "remote") return false;
	const url = cfg.gateway.remote?.url?.trim();
	if (!url) return false;
	try {
		const parsed = new URL(url);
		if (parsed.hostname === "127.0.0.1" || parsed.hostname === "localhost" || parsed.hostname === "::1") return false;
		if (parsed.protocol === "https:") return false;
		return !isGatewayTlsEnabled(cfg);
	} catch {
		return true;
	}
}
function isTailnetBindUnavailable(cfg) {
	const plan = resolveGatewayListenPlan({ cfg });
	return plan.bindMode === "tailnet" && isLoopbackHost(plan.bindHost);
}
//#endregion
export { assertExposureConfig, collectExposureConflicts, isGatewayTlsEnabled, isRemoteGatewayInsecure, isTailnetBindUnavailable, resolveEffectiveTailscaleMode };

//# sourceMappingURL=exposure-guards.js.map