/**
 * Self-aligning template upgrades for SF config files.
 *
 * Goal: when sf evolves, projects' .sf/preferences.yaml gets brought into
 * alignment WITHOUT human intervention. The file's frontmatter stamps
 * `last_synced_with_sf: <semver>`; on every load, sf compares to its own
 * version and silently re-writes the file to match.
 *
 * What this is NOT: a human-facing warning system. The end-user shouldn't
 * have to read drift advisories; sf keeps its own house in order.
 */
import { existsSync, writeFileSync } from "node:fs";
import { serializePreferencesToFrontmatter } from "./preferences-serializer.js";
export function detectTemplateDrift(prefs) {
	const toVersion = process.env.SF_VERSION || "0.0.0";
	const fromVersion = prefs.last_synced_with_sf || "0.0.0";
	// Skip when either side is unknown — better to no-op than re-write with
	// "0.0.0" stamp on a file that was hand-edited or generated outside the
	// normal sf load path.
	if (toVersion === "0.0.0" || fromVersion === "0.0.0") {
		return { fromVersion, toVersion, needsUpgrade: false };
	}
	return {
		fromVersion,
		toVersion,
		needsUpgrade: fromVersion !== toVersion,
	};
}
/**
 * If the file at `path` is drifted from current sf, re-render its
 * frontmatter with a fresh `last_synced_with_sf` stamp (and any other
 * fields that may have been migrated by validatePreferences). Body is
 * preserved verbatim — only the leading `--- ... ---` block is rewritten.
 *
 * Returns the (possibly stamp-updated) prefs object so callers can use the
 * canonical view without re-reading the file.
 *
 * Failure modes are non-fatal: if the file disappeared, frontmatter can't
 * be located, or write fails, the original prefs are returned unchanged.
 * sf load paths must continue working even if disk-level upgrade is blocked.
 */
export function upgradePreferencesFileIfDrifted(path, prefs) {
	const drift = detectTemplateDrift(prefs);
	if (!drift.needsUpgrade) return prefs;
	const upgraded = {
		...prefs,
		last_synced_with_sf: drift.toVersion,
	};
	if (!existsSync(path)) return upgraded;
	try {
		writeFileSync(path, serializePreferencesToFrontmatter(upgraded), "utf-8");
	} catch {
		// Read-only filesystem, permission error, etc. — not fatal.
	}
	return upgraded;
}
