import { loadConfig } from "../config/loader.js";
import "../config/index.js";
import { isRestartEnabled } from "../config/commands.flags.js";
import { restartGatewayProcessWithFreshPid } from "./respawn.js";
import { acquireGatewayLock } from "./lock.js";
import { consumeGatewayRestartIntentSync, consumeGatewaySigusr1RestartAuthorization, isGatewaySigusr1RestartExternallyAllowed, resetGatewayRestartStateForInProcessRestart, scheduleGatewaySigusr1Restart, setGatewaySigusr1RestartPolicy } from "../infra/restart.js";
//#region src/gateway/run-loop.ts
/**
* Gateway Run Loop - Core run loop for gateway process management
*/
async function runGatewayLoop(opts) {
	setGatewaySigusr1RestartPolicy({ allowExternal: isRestartEnabled(loadConfig(opts.configPath)) });
	let lock = await acquireGatewayLock(opts.configPath, { port: opts.port });
	let server = null;
	let shuttingDown = false;
	let restartResolver = null;
	const cleanupSignals = () => {
		process.removeListener("SIGTERM", onSigterm);
		process.removeListener("SIGINT", onSigint);
		process.removeListener("SIGUSR1", onSigusr1);
	};
	const exitProcess = (code) => {
		cleanupSignals();
		process.exit(code);
	};
	const releaseLock = async () => {
		if (lock) {
			await lock.release();
			lock = null;
		}
	};
	const handleRestartAfterClose = async () => {
		await releaseLock();
		const respawn = restartGatewayProcessWithFreshPid();
		if (respawn.mode === "spawned" || respawn.mode === "supervised") {
			const modeLabel = respawn.mode === "spawned" ? `spawned pid ${respawn.pid ?? "unknown"}` : "supervisor restart";
			console.log(`[GatewayRunLoop] Restart mode: full process restart (${modeLabel})`);
			exitProcess(0);
			return;
		}
		if (respawn.mode === "failed") console.warn(`[GatewayRunLoop] Full process restart failed: ${respawn.detail ?? "unknown error"}`);
		else console.log("[GatewayRunLoop] Restart mode: in-process restart (XOPC_NO_RESPAWN)");
		resetGatewayRestartStateForInProcessRestart();
		try {
			lock = await acquireGatewayLock(opts.configPath, { port: opts.port });
		} catch (err) {
			console.error(`[GatewayRunLoop] Failed to reacquire lock: ${String(err)}`);
			exitProcess(1);
			return;
		}
		shuttingDown = false;
		restartResolver?.();
	};
	const handleStopAfterClose = async () => {
		await releaseLock();
		exitProcess(0);
	};
	const DRAIN_TIMEOUT_MS = 3e4;
	const SHUTDOWN_TIMEOUT_MS = 15e3;
	const requestShutdown = (action, signal) => {
		if (shuttingDown) return;
		shuttingDown = true;
		const isRestart = action === "restart";
		console.log(`[GatewayRunLoop] Received ${signal}; ${isRestart ? "restarting" : "shutting down"}`);
		cleanupSignals();
		const forceExitMs = isRestart ? DRAIN_TIMEOUT_MS + SHUTDOWN_TIMEOUT_MS : SHUTDOWN_TIMEOUT_MS;
		const forceExitTimer = setTimeout(() => {
			console.error("[GatewayRunLoop] Shutdown timed out; force exiting");
			exitProcess(0);
		}, forceExitMs);
		(async () => {
			try {
				if (isRestart) console.log("[GatewayRunLoop] Draining active tasks before restart...");
				await server?.close?.({
					reason: isRestart ? "gateway restarting" : "gateway stopping",
					restartExpectedMs: isRestart ? 1500 : null
				});
			} catch (err) {
				console.error(`[GatewayRunLoop] Shutdown error: ${String(err)}`);
			} finally {
				clearTimeout(forceExitTimer);
				server = null;
				if (isRestart) await handleRestartAfterClose();
				else await handleStopAfterClose();
			}
		})();
	};
	const onSigterm = () => {
		console.log("[GatewayRunLoop] SIGTERM received");
		requestShutdown(consumeGatewayRestartIntentSync() ? "restart" : "stop", "SIGTERM");
	};
	const onSigint = () => {
		console.log("[GatewayRunLoop] SIGINT received");
		requestShutdown("stop", "SIGINT");
	};
	const onSigusr1 = () => {
		console.log("[GatewayRunLoop] SIGUSR1 received");
		if (!consumeGatewaySigusr1RestartAuthorization()) {
			if (!isGatewaySigusr1RestartExternallyAllowed()) {
				console.warn("[GatewayRunLoop] SIGUSR1 restart ignored (commands.restart=false or unauthorized).");
				return;
			}
			if (shuttingDown) {
				console.log("[GatewayRunLoop] Received SIGUSR1 during shutdown; ignoring");
				return;
			}
			scheduleGatewaySigusr1Restart({
				delayMs: 0,
				reason: "SIGUSR1",
				onRestart: () => requestShutdown("restart", "SIGUSR1")
			});
			return;
		}
		requestShutdown("restart", "SIGUSR1");
	};
	process.on("SIGTERM", onSigterm);
	process.on("SIGINT", onSigint);
	process.on("SIGUSR1", onSigusr1);
	try {
		while (true) {
			console.log("[GatewayRunLoop] Starting gateway server...");
			try {
				server = await opts.start();
			} catch (err) {
				console.error("[GatewayRunLoop] Failed to start gateway server:", err);
				await releaseLock();
				exitProcess(1);
				return;
			}
			await new Promise((resolve) => {
				restartResolver = resolve;
			});
			console.log("[GatewayRunLoop] Restart signal received, restarting gateway...");
		}
	} finally {
		await releaseLock();
		cleanupSignals();
	}
}
//#endregion
export { runGatewayLoop };

//# sourceMappingURL=run-loop.js.map