/**
 * The schema version this build of sf reads and writes natively.
 *
 * Bump this AT THE SAME TIME you register a new Migration entry below.
 * Do not bump speculatively — projects with `version > current` get a
 * "prefs from a newer sf, ignoring unknown fields" warning, which is
 * the right behavior for forward compatibility but signals churn to users.
 */
export const CURRENT_PREFERENCES_SCHEMA_VERSION = 1;
/**
 * Forward-only migration chain. Sorted by `from` ascending. Empty until
 * the first real schema change ships — the framework is in place so the
 * first bump (e.g. to v2) is a one-line change here, not a refactor.
 */
export const MIGRATIONS = [];
/**
 * Apply forward migrations until prefs.version === CURRENT, or fail.
 * If the input is at a higher version than current, return as-is and flag
 * `fromFuture = true` — caller decides whether to warn or refuse.
 *
 * Treats `version === undefined` as version 1 (the implicit pre-versioning
 * baseline) so old projects without explicit version get migrated.
 */
/**
 * Apply forward migrations to transform preferences to the current schema version.
 */
export function migrateForward(input) {
	const startVersion = input.version ?? 1;
	if (startVersion > CURRENT_PREFERENCES_SCHEMA_VERSION) {
		return { preferences: input, applied: [], fromFuture: true };
	}
	if (startVersion === CURRENT_PREFERENCES_SCHEMA_VERSION) {
		return {
			preferences: { ...input, version: CURRENT_PREFERENCES_SCHEMA_VERSION },
			applied: [],
			fromFuture: false,
		};
	}
	let prefs = input;
	const applied = [];
	let v = startVersion;
	while (v < CURRENT_PREFERENCES_SCHEMA_VERSION) {
		const step = MIGRATIONS.find((m) => m.from === v);
		if (!step) {
			throw new Error(
				`No migration registered from prefs schema v${v} → v${v + 1}. ` +
					`This is a bug in sf — bumping CURRENT_PREFERENCES_SCHEMA_VERSION ` +
					`requires a matching Migration entry in preferences-migrations.ts.`,
			);
		}
		prefs = step.apply(prefs);
		applied.push(step);
		v = step.to;
	}
	return { preferences: prefs, applied, fromFuture: false };
}
/**
 * Compare a project's prefs against the current schema and report drift
 * that isn't a hard error but worth surfacing to the user.
 *
 * Currently:
 *   - `version > current` (prefs from newer sf — fields may be silently dropped)
 *   - `version === undefined` (legacy file, would benefit from explicit version)
 *
 * Future: deprecated-key detection, missing-required-field detection.
 */
/**
 * Check preferences for schema version drift and return any warnings.
 */
export function checkPreferencesDrift(prefs) {
	const warnings = [];
	if (prefs.version === undefined) {
		warnings.push(
			"prefs file has no explicit `version` — assuming v1. Add " +
				"`version: 1` (or higher) to silence this warning and pin the " +
				"schema this file was authored against.",
		);
	} else if (prefs.version > CURRENT_PREFERENCES_SCHEMA_VERSION) {
		warnings.push(
			`prefs file declares version ${prefs.version} but this sf build ` +
				`understands up to v${CURRENT_PREFERENCES_SCHEMA_VERSION}. ` +
				`Unknown fields will be ignored. Upgrade sf or downgrade the file.`,
		);
	}
	return { warnings };
}
