import { createLogger } from "../../../utils/logger/index.js";
import { init_logger } from "../../../utils/logger.js";
import { clearGatewayRestartIntentSync, writeGatewayRestartIntentSync } from "../../../infra/restart.js";
//#region src/cli/commands/gateway/lifecycle-core.ts
init_logger();
const log = createLogger("DaemonLifecycle");
function emitResult(options, payload) {
	if (options.json) {
		console.log(JSON.stringify(payload, null, 2));
		return;
	}
	if (payload.ok) {
		if (payload.message) console.log(`✅ ${payload.message}`);
		for (const warning of payload.warnings ?? []) console.warn(`⚠️  ${warning}`);
		return;
	}
	if (payload.error) console.error(`❌ ${payload.error}`);
	for (const hint of payload.hints ?? []) console.log(`💡 ${hint}`);
}
function createFail(options) {
	return (message, hints, diagnostics, opts = options) => {
		emitResult(opts, {
			ok: false,
			error: message,
			hints
		});
		for (const line of diagnostics ?? []) if (!opts.json) console.log(`   ${line}`);
		process.exit(1);
	};
}
async function resolveServiceLoadedOrFail(service, fail) {
	try {
		return await service.isLoaded({ env: process.env });
	} catch (err) {
		fail(`Gateway service check failed: ${String(err)}`);
		return null;
	}
}
async function handleServiceNotLoaded(params) {
	emitResult(params.options, {
		ok: true,
		result: "not-loaded",
		message: `Gateway service ${params.service.notLoadedText}.`,
		hints: params.renderStartHints()
	});
}
async function checkAndWarnTokenDrift(service, options) {
	const warnings = [];
	try {
		const serviceToken = (await service.readCommand(process.env))?.environment?.XOPC_GATEWAY_TOKEN;
		if (!serviceToken) return warnings;
		const { loadConfig } = await import("../../../config/index.js");
		const { resolveConfigPath } = await import("../../../config/paths.js");
		const configToken = loadConfig(resolveConfigPath())?.gateway?.auth?.token;
		if (configToken && serviceToken !== configToken) {
			const warning = "Token drift detected: service token differs from config. Run `xopc gateway service install --force` to sync.";
			warnings.push(warning);
			if (!options.json) console.warn(`⚠️  ${warning}`);
		}
	} catch {}
	return warnings;
}
async function runServiceStop(params) {
	const options = params.opts ?? {};
	const fail = createFail(options);
	const loaded = await resolveServiceLoadedOrFail(params.service, fail);
	if (loaded === null) return;
	if (!loaded) {
		try {
			const handled = await params.onNotLoaded?.({
				json: Boolean(options.json),
				fail
			});
			if (handled) {
				emitResult(options, {
					ok: true,
					result: handled.result,
					message: handled.message,
					warnings: handled.warnings
				});
				return;
			}
		} catch (err) {
			fail(`Gateway stop failed: ${String(err)}`);
			return;
		}
		await handleServiceNotLoaded({
			service: params.service,
			renderStartHints: () => ["xopc gateway service install", "xopc gateway"],
			options
		});
		return;
	}
	try {
		await params.service.stop({
			env: process.env,
			disable: options.disable
		});
		emitResult(options, {
			ok: true,
			result: "stopped",
			message: options.disable ? "Gateway stopped and disabled (will not respawn)." : "Gateway stopped."
		});
	} catch (err) {
		log.error({ err }, "Failed to stop gateway");
		fail(`Gateway stop failed: ${String(err)}`);
	}
}
async function runServiceRestart(params) {
	const options = params.opts ?? {};
	const fail = createFail(options);
	const warnings = [];
	let handledRecovery = null;
	const loaded = await resolveServiceLoadedOrFail(params.service, fail);
	if (loaded === null) return;
	if (!loaded) {
		try {
			handledRecovery = await params.onNotLoaded?.({
				json: Boolean(options.json),
				fail
			}) ?? null;
		} catch (err) {
			fail(`Gateway restart failed: ${String(err)}`);
			return;
		}
		if (!handledRecovery) {
			await handleServiceNotLoaded({
				service: params.service,
				renderStartHints: params.renderStartHints,
				options
			});
			return;
		}
		if (handledRecovery.warnings?.length) warnings.push(...handledRecovery.warnings);
	}
	if (loaded && params.checkTokenDrift) warnings.push(...await checkAndWarnTokenDrift(params.service, options));
	try {
		if (loaded) {
			let wroteRestartIntent = false;
			wroteRestartIntent = writeGatewayRestartIntentSync({ targetPid: (await params.service.readRuntime(process.env).catch(() => null))?.pid });
			try {
				await params.service.restart({ env: process.env });
			} catch (err) {
				if (wroteRestartIntent) clearGatewayRestartIntentSync();
				throw err;
			}
		}
		if (params.postRestartCheck) await params.postRestartCheck({
			options,
			fail
		});
		if (options.wait) {
			const timeoutMs = parseWaitTimeout(options.wait);
			const { loadConfig } = await import("../../../config/index.js");
			const { resolveConfigPath } = await import("../../../config/paths.js");
			const config = loadConfig(resolveConfigPath());
			const port = typeof config.gateway?.port === "number" ? config.gateway.port : 18790;
			const { waitForRestartHealth } = await import("./restart-health.js");
			const snapshot = await waitForRestartHealth({
				service: params.service,
				port,
				timeoutMs,
				onProgress: () => {
					if (!options.json) process.stdout.write(".");
				}
			});
			if (!options.json) process.stdout.write("\n");
			if (!snapshot.healthy) {
				fail(`Restart health check failed: ${snapshot.waitOutcome ?? "timeout"}`, ["xopc gateway logs"]);
				return;
			}
			emitResult(options, {
				ok: true,
				result: "healthy",
				message: `Gateway restarted and healthy (pid ${snapshot.runtime?.pid ?? "unknown"}, ${snapshot.elapsedMs ?? 0}ms).`,
				warnings: warnings.length ? warnings : void 0
			});
			return;
		}
		emitResult(options, {
			ok: true,
			result: "restarted",
			message: handledRecovery?.message ?? "Gateway restart completed.",
			warnings: warnings.length ? warnings : void 0
		});
	} catch (err) {
		log.error({ err }, "Failed to restart gateway");
		fail(`Gateway restart failed: ${String(err)}`, params.renderStartHints());
	} finally {
		clearGatewayRestartIntentSync();
	}
}
async function executeDaemonUninstall(options = {}) {
	const { resolveGatewayService, isDaemonAvailableAsync } = await import("../../../daemon/service.js");
	if (!await isDaemonAvailableAsync()) {
		emitResult(options, {
			ok: false,
			error: "Daemon service not available on this platform"
		});
		process.exit(1);
	}
	const service = await resolveGatewayService();
	if (await service.isLoaded({ env: process.env }).catch(() => false)) try {
		await service.stop({ env: process.env });
	} catch {}
	try {
		await service.uninstall({ env: process.env });
		emitResult(options, {
			ok: true,
			result: "uninstalled",
			message: "Gateway service uninstalled."
		});
	} catch (err) {
		log.error({ err }, "Failed to uninstall gateway service");
		emitResult(options, {
			ok: false,
			error: `Failed to uninstall: ${String(err)}`
		});
		process.exit(1);
	}
}
function parseWaitTimeout(wait) {
	const match = wait.match(/^(\d+)(s|m|ms)?$/);
	if (!match) return 6e4;
	const value = parseInt(match[1], 10);
	switch (match[2] || "s") {
		case "ms": return value;
		case "m": return value * 6e4;
		default: return value * 1e3;
	}
}
//#endregion
export { executeDaemonUninstall, runServiceRestart, runServiceStop };

//# sourceMappingURL=lifecycle-core.js.map