import { A as applyLegacyDoctorMigrations } from "./io.runtime-CNGn9TXj.js";
import { t as findLegacyConfigIssues } from "./legacy-pGW3ZP3t.js";
import { X as stampConfigWriteMetadata, _ as validateConfigObjectRaw, c as resolveManagedUnsetPathsForWrite, h as validateConfigObjectWithPlugins, s as applyUnsetPathsForWrite } from "./io.types-IrfFC0Eb.js";
import { r as containsConfigIncludeDirective } from "./io.read-helpers-BJhqVbGj.js";
import { r as replaceConfigFile } from "./mutate-Cg2fvWmm.js";
import "./config-D_ojUgx2.js";
import { n as findDoctorLegacyConfigIssues } from "./legacy-config-issues-erBNJdDi.js";
import { isDeepStrictEqual } from "node:util";
//#region src/commands/doctor/shared/automatic-startup-config-repair.ts
function admitStartupConfigRepairSnapshot(snapshot) {
	return !snapshot.valid && snapshot.exists && snapshot.raw !== null && (snapshot.includedPaths?.length ?? 0) === 0 && !containsConfigIncludeDirective(snapshot.parsed);
}
function buildStartupConfigRepairPlan(snapshot, config, changes) {
	return {
		config,
		changes,
		snapshot: {
			...snapshot,
			sourceConfig: config,
			resolved: config,
			runtimeConfig: config,
			config,
			valid: true,
			issues: [],
			legacyIssues: []
		}
	};
}
/** Admits only complete, deterministic single-file legacy migrations for startup. */
function planStartupConfigRepair(snapshot) {
	if (!admitStartupConfigRepairSnapshot(snapshot)) return null;
	const { next: config, changes } = applyLegacyDoctorMigrations(snapshot.sourceConfig, {
		authoredRaw: snapshot.parsed,
		resolvedRaw: snapshot.sourceConfig
	});
	if (!config || isDeepStrictEqual(config, snapshot.sourceConfig) || !validateConfigObjectWithPlugins(config).ok || findDoctorLegacyConfigIssues(config, config).length > 0) return null;
	return buildStartupConfigRepairPlan(snapshot, config, changes);
}
/**
* State-free repairable preview for callers that run before the shared state database
* may be touched (gateway pre-bootstrap selection, backup discovery). It skips plugin
* doctor contracts and plugin validation, so it can admit a snapshot the full planner
* later refuses — the preflight committer and canonical-write matcher stay authoritative,
* and a refused commit keeps today's fail-closed startup refusal.
*/
function planStartupConfigRepairPreview(snapshot) {
	if (!admitStartupConfigRepairSnapshot(snapshot)) return null;
	const { next: config, changes } = applyLegacyDoctorMigrations(snapshot.sourceConfig, {
		authoredRaw: snapshot.parsed,
		resolvedRaw: snapshot.sourceConfig
	}, { pluginContracts: false });
	if (!config || isDeepStrictEqual(config, snapshot.sourceConfig) || !validateConfigObjectRaw(config).ok || findLegacyConfigIssues(config, config).length > 0) return null;
	return buildStartupConfigRepairPlan(snapshot, config, changes);
}
/**
* Repairable-snapshot trust check for callers that run before startup state admission
* (gateway pre-bootstrap selection, backup discovery). The full planner covers
* plugin-contract migrations but reads the installed-plugin registry from the shared
* state database; when that store is unreachable, fall back to the state-free preview
* so core-key repairs stay reachable and everything else keeps today's fail-closed
* refusal. The preflight committer and canonical-write matcher stay authoritative.
*/
function resolveStartupConfigSnapshot(snapshot) {
	if (snapshot.valid) return snapshot;
	try {
		return planStartupConfigRepair(snapshot)?.snapshot;
	} catch {
		return planStartupConfigRepairPreview(snapshot)?.snapshot;
	}
}
/** Matches only the canonical writer result for a previously admitted startup repair. */
function isStartupConfigRepairResult(before, after) {
	const plan = planStartupConfigRepair(before);
	const expected = plan ? stampConfigWriteMetadata(applyUnsetPathsForWrite(plan.config, resolveManagedUnsetPathsForWrite(void 0)), void 0, void 0, before.parsed) : null;
	return Boolean(expected && after.valid && before.path === after.path && isDeepStrictEqual(expected, after.sourceConfig));
}
/** Commits a planned repair against the exact snapshot admitted under the startup lease. */
async function commitStartupConfigRepair(plan, snapshot) {
	await replaceConfigFile({
		nextConfig: plan.config,
		snapshot,
		afterWrite: {
			mode: "none",
			reason: "startup migration"
		},
		writeOptions: {
			auditOrigin: "doctor",
			skipOutputLogs: true,
			skipRuntimeSnapshotRefresh: true
		}
	});
}
//#endregion
export { resolveStartupConfigSnapshot as i, isStartupConfigRepairResult as n, planStartupConfigRepair as r, commitStartupConfigRepair as t };
