import { o as normalizeLowercaseStringOrEmpty } from "./string-coerce-CIXf7egm.js";
import { n as isTruthyEnvValue } from "./env-DDC-EStD.js";
import { a as isDefaultInstallIdentity } from "./paths-BBSTUjD5.js";
import { t as formatCliCommand } from "./command-format-HwSAdvXB.js";
import { r as runCommandWithTimeout } from "./exec-B6wf9wmM.js";
import { a as readGatewayServiceState, o as resolveGatewayService } from "./service-CO5q96-E.js";
import { t as note } from "./note-YH_0kY-3.js";
import { n as createUpdateProgress, t as resolveUnsafeUpdateRecoveryGuidance } from "./update-recovery-guidance-CWM2JJbG.js";
import { t as runGatewayUpdate } from "./update-runner-UGBQUs75.js";
import { i as isServiceRepairExternallyManaged, t as EXTERNAL_SERVICE_REPAIR_NOTE } from "./doctor-service-repair-policy-DCriyRvl.js";
import path from "node:path";
import fs from "node:fs/promises";
//#region src/commands/doctor-update.ts
/** Optional pre-doctor update prompt for source checkouts and package installs. */
async function resolveComparablePath(target) {
	return await fs.realpath(target).catch(() => path.resolve(target));
}
async function detectOpenClawGitCheckout(root) {
	const res = await runCommandWithTimeout([
		"git",
		"-C",
		root,
		"rev-parse",
		"--show-toplevel"
	], { timeoutMs: 5e3 }).catch(() => null);
	if (!res) return "unknown";
	if (res.code !== 0) {
		if (normalizeLowercaseStringOrEmpty(res.stderr).includes("not a git repository")) return "not-git";
		return "unknown";
	}
	return await resolveComparablePath(res.stdout.trim()) === await resolveComparablePath(root) ? "git" : "not-git";
}
/** Offers to update OpenClaw before doctor when running interactively from an updatable install. */
async function maybeOfferUpdateBeforeDoctor(params) {
	if (!(!isTruthyEnvValue(process.env.OPENCLAW_UPDATE_IN_PROGRESS) && params.options.nonInteractive !== true && params.options.yes !== true && params.options.repair !== true && process.stdin.isTTY) || !params.root) return { updated: false };
	const git = await detectOpenClawGitCheckout(params.root);
	if (git === "git") {
		if (!await params.confirm({
			message: "Update OpenClaw from git before running doctor?",
			initialValue: true
		})) return { updated: false };
		const updateRoot = params.root;
		const externallyManaged = isServiceRepairExternallyManaged();
		const serviceLifecycle = isDefaultInstallIdentity(process.env) && !externallyManaged ? await import("./managed-gateway-update.runtime.js") : void 0;
		let inspection = await serviceLifecycle?.maybeStopManagedServiceBeforeMutableUpdate({
			updateInstallKind: "git",
			root: updateRoot,
			shouldRestart: true,
			jsonMode: false,
			phase: "inspect"
		});
		if (inspection?.blockMessage) {
			note(inspection.blockMessage, "Update");
			return { updated: false };
		}
		if (inspection?.serviceMutationSkipMessage) note(inspection.serviceMutationSkipMessage, "Update");
		let gitMutationAuthorized = false;
		note("Running update…", "Update");
		const { progress, stop } = createUpdateProgress(process.stdout.isTTY);
		let result;
		try {
			result = await runGatewayUpdate({
				cwd: updateRoot,
				argv1: process.argv[1],
				progress,
				allowGatewayServiceRepair: inspection?.serviceUpdateVerdict?.kind === "owned" && inspection.serviceUpdateVerdict.refreshDefinition,
				allowGatewayActivation: Boolean(inspection?.running && inspection.serviceUpdateVerdict?.kind === "owned"),
				beforeGitMutation: serviceLifecycle ? async () => {
					const previousSkip = inspection?.serviceMutationSkipMessage;
					inspection = await serviceLifecycle.maybeStopManagedServiceBeforeMutableUpdate({
						updateInstallKind: "git",
						root: updateRoot,
						shouldRestart: true,
						jsonMode: false,
						phase: "prepare"
					});
					if (inspection.blockMessage) throw new Error(inspection.blockMessage);
					if (inspection.serviceMutationSkipMessage !== previousSkip && inspection.serviceMutationSkipMessage) note(inspection.serviceMutationSkipMessage, "Update");
					gitMutationAuthorized = true;
					return serviceLifecycle.resolvePreparedGatewayUpdatePolicy(inspection, true);
				} : void 0
			});
		} catch (err) {
			if (inspection?.stopped && gitMutationAuthorized) note(`The gateway service remains stopped because the source checkout may be partially mutated. Inspect and repair the checkout, then restart the gateway manually with \`${formatCliCommand("openclaw gateway restart")}\`.`, "Update");
			else if (inspection?.stopped) await serviceLifecycle?.maybeRestartServiceAfterFailedMutableUpdate({
				preManagedServiceStop: inspection,
				jsonMode: false
			});
			throw err;
		} finally {
			stop();
		}
		note([
			`Status: ${result.status}`,
			`Mode: ${result.mode}`,
			result.root && `Root: ${result.root}`,
			result.reason && `Reason: ${result.reason}`
		].filter(Boolean).join("\n"), "Update result");
		if (result.status !== "ok") {
			if (result.recovery?.serviceRestartSafe === false) {
				const managedGatewayStopped = inspection?.stopped === true;
				const summary = managedGatewayStopped ? `Managed gateway remains stopped because update recovery could not prove a runnable installation (${result.recovery.reason}).` : `Update recovery could not prove a runnable installation (${result.recovery.reason}).`;
				const keepStopped = managedGatewayStopped ? "\nKeep the gateway stopped until the update succeeds." : "";
				note(`${summary}\n${resolveUnsafeUpdateRecoveryGuidance(result.recovery.reason)}${keepStopped}`, "Update");
			} else await serviceLifecycle?.maybeRestartServiceAfterFailedMutableUpdate({
				root: result.root,
				preManagedServiceStop: inspection,
				jsonMode: false
			});
			return {
				updated: true,
				handled: false
			};
		}
		if (externallyManaged) note(EXTERNAL_SERVICE_REPAIR_NOTE, "Update");
		else if (inspection?.stopped && inspection.serviceEnv && serviceLifecycle) try {
			const serviceState = await readGatewayServiceState(resolveGatewayService(), {
				env: inspection.serviceEnv,
				requireEffective: true
			});
			const verdict = await serviceLifecycle.revalidateManagedGatewayServiceAfterUpdate({
				state: serviceState,
				root: updateRoot,
				preManagedServiceStop: inspection
			});
			if (!await serviceLifecycle.maybeRestartService({
				shouldRestart: true,
				result,
				channel: "dev",
				opts: {},
				refreshServiceEnv: false,
				serviceUpdateVerdict: verdict.kind === "owned" ? {
					...verdict,
					refreshDefinition: false
				} : verdict,
				serviceEnv: serviceState.env,
				gatewayPort: await serviceLifecycle.resolveUpdatedGatewayRestartPort({
					serviceEnv: serviceState.env,
					serviceCommand: serviceState.command
				}),
				requireRunningServiceAfterRestart: true,
				timeoutMs: 12e5
			})) throw new Error("Gateway restart was not verified; run `openclaw gateway status --deep` before restarting manually.");
			note("Restarted the running gateway service after updating OpenClaw.", "Update");
		} catch (err) {
			const message = "Update completed, but gateway service restart failed";
			params.runtime.error(`${message}: ${String(err)}`);
			params.outro(`${message}.`);
			params.runtime.exit(1);
			return {
				updated: true,
				handled: true
			};
		}
		params.outro("Update completed (doctor already ran as part of the update).");
		return {
			updated: true,
			handled: true
		};
	}
	if (git === "not-git") note(["This install is not a git checkout.", `Run \`${formatCliCommand("openclaw update")}\` to update via your package manager (npm/pnpm), then rerun doctor.`].join("\n"), "Update");
	return { updated: false };
}
//#endregion
export { maybeOfferUpdateBeforeDoctor };
