/**
 * operating-model.js — canonical SF operating vocabulary.
 *
 * Purpose: keep UOK, command surfaces, and policy evidence aligned on the same
 * run-control and permission-profile model instead of scattered string aliases.
 *
 * Consumer: UOK kernel ledgers, execution-policy decisions, and command surfaces
 * that need stable product terms.
 */

export const WORK_MODES = Object.freeze([
	"chat",
	"plan",
	"build",
	"review",
	"repair",
	"research",
]);

export const RUN_CONTROL_MODES = Object.freeze([
	"manual",
	"assisted",
	"autonomous",
]);

export const PERMISSION_PROFILES = Object.freeze([
	"restricted",
	"normal",
	"trusted",
	"unrestricted",
]);

export const MODEL_MODES = Object.freeze(["fast", "smart", "deep"]);

/**
 * Returns true for a canonical SF work mode.
 *
 * Purpose: let surfaces reject aliases before they leak into state.
 *
 * Consumer: command parsers and session state builders.
 */
export function isWorkMode(value) {
	return WORK_MODES.includes(value);
}

/**
 * Returns true for a canonical SF run-control mode.
 *
 * Purpose: let surfaces reject aliases such as "auto" or "full" before they
 * leak into UOK ledgers or policy records.
 *
 * Consumer: command parsers and UOK context builders.
 */
export function isRunControlMode(value) {
	return RUN_CONTROL_MODES.includes(value);
}

/**
 * Returns true for a canonical SF permission profile.
 *
 * Purpose: keep trust/sandbox posture separate from whether the loop continues.
 *
 * Consumer: execution-policy resolution and UOK context builders.
 */
export function isPermissionProfile(value) {
	return PERMISSION_PROFILES.includes(value);
}

/**
 * Returns true for a canonical SF model mode.
 *
 * Purpose: let routing and command surfaces reject invalid model mode names.
 *
 * Consumer: model selection and command parsers.
 */
export function isModelMode(value) {
	return MODEL_MODES.includes(value);
}

/**
 * Resolve an unknown work mode to the conservative chat mode.
 *
 * Purpose: fail closed when work mode is absent or misspelled.
 *
 * Consumer: session state construction and command handlers.
 */
export function resolveWorkMode(value) {
	return isWorkMode(value) ? value : "chat";
}

/**
 * The three primary SF intent modes.
 *
 * Purpose: give users one clear choice that signals intent and sets sensible
 * defaults for runControl and modelMode — without hard-blocking any behaviour.
 * Build mode can still ask and plan; Ask mode can still produce code. The mode
 * tells SF what you are primarily here for so it can shape its posture.
 *
 * Consumer: /mode command, Shift+Tab cycling, status display, auto-dispatch
 * context injection.
 */
export const SF_MODE_PRESETS = Object.freeze({
	ask: {
		label: "Ask",
		description: "Explore, discuss, and plan — user is driving, SF assists",
		workMode: "chat",
		runControl: "manual",
		modelMode: "fast",
		permissionProfile: "normal",
	},
	build: {
		label: "Build",
		description:
			"SF executes autonomously — user steps back, no permission prompts",
		workMode: "build",
		runControl: "autonomous",
		modelMode: "smart",
		permissionProfile: "unrestricted",
	},
});

export const SF_MODE_PRESET_NAMES = Object.freeze(Object.keys(SF_MODE_PRESETS));

/**
 * Return the preset definition for a given name, or null if not a preset.
 *
 * Purpose: let command handlers and the Shift+Tab handler resolve a preset
 * name to its full dimension values in one call.
 *
 * Consumer: handleModeCommand, steerable-autonomous-extension.js.
 */
export function resolvePreset(name) {
	return SF_MODE_PRESETS[name?.toLowerCase()] ?? null;
}

/**
 * Infer the active preset name from current mode dimensions, or null.
 *
 * Purpose: let the status display show "Build" instead of
 * "build · autonomous · smart" when the settings match a known preset.
 *
 * Consumer: formatModeState in core.js handler.
 */
export function inferPresetName(mode) {
	if (!mode) return null;
	for (const [name, preset] of Object.entries(SF_MODE_PRESETS)) {
		if (
			mode.workMode === preset.workMode &&
			mode.runControl === preset.runControl &&
			mode.modelMode === preset.modelMode &&
			mode.permissionProfile === preset.permissionProfile
		) {
			return name;
		}
	}
	return null;
}

/**
 * Resolve an unknown run-control value to the conservative manual mode.
 *
 * Purpose: fail closed when a caller passes missing or unsupported run-control
 * input, preserving the manual/assisted/autonomous vocabulary.
 *
 * Consumer: UOK context construction and future protocol adapters.
 */
export function resolveRunControlMode(value) {
	return isRunControlMode(value) ? value : "manual";
}

/**
 * Resolve an unknown permission profile to restricted.
 *
 * Purpose: fail closed when permission posture is absent or misspelled.
 *
 * Consumer: execution-policy classifiers and UOK ledgers.
 */
export function resolvePermissionProfile(value) {
	return isPermissionProfile(value) ? value : "restricted";
}

/**
 * Resolve an unknown model mode to smart.
 *
 * Purpose: provide a safe default when model mode is absent.
 *
 * Consumer: model routing and command handlers.
 */
export function resolveModelMode(value) {
	return isModelMode(value) ? value : "smart";
}

/**
 * Derive the UOK run-control mode from the live auto session state.
 *
 * Purpose: preserve the old `stepMode` runtime bit as storage detail while UOK
 * ledgers expose the product vocabulary: assisted or autonomous.
 *
 * Consumer: runAutoLoopWithUok before recording kernel lifecycle events.
 */
export function runControlModeForSession(session) {
	return session?.stepMode ? "assisted" : "autonomous";
}

/**
 * Choose the default permission profile for a run-control mode.
 *
 * Purpose: make loop autonomy independent from trust level while giving every
 * UOK run a concrete policy posture for evidence and future enforcement.
 *
 * Consumer: UOK kernel run ledger and audit envelope.
 */
export function defaultPermissionProfileForRunControl(mode) {
	return resolveRunControlMode(mode) === "manual" ? "restricted" : "normal";
}

/**
 * Choose the default model mode for a work mode.
 *
 * Purpose: guide model routing without replacing explicit model selection.
 *
 * Consumer: model routing and session initialization.
 */
export function defaultModelModeForWorkMode(workMode) {
	switch (resolveWorkMode(workMode)) {
		case "plan":
		case "review":
		case "research":
			return "deep";
		case "build":
		case "repair":
			return "smart";
		default:
			return "fast";
	}
}

/**
 * Map model mode to complexity tier for routing.
 *
 * Purpose: bridge the user-facing modelMode vocabulary (fast/smart/deep)
 * to the internal complexity tier system (light/standard/heavy).
 *
 * Consumer: complexity classifier, model router, /rate feedback.
 */
export function modelModeToTier(modelMode) {
	switch (resolveModelMode(modelMode)) {
		case "fast":
			return "light";
		case "deep":
			return "heavy";
		default:
			return "standard";
	}
}

/**
 * Map complexity tier to model mode.
 *
 * Purpose: display the current tier in user-facing modelMode vocabulary.
 *
 * Consumer: TUI badges, status output.
 */
export function tierToModelMode(tier) {
	switch (tier) {
		case "light":
			return "fast";
		case "heavy":
			return "deep";
		default:
			return "smart";
	}
}

/**
 * Build a canonical mode state object.
 *
 * Purpose: standardize the five orthogonal axes so every surface stores
 * and displays the same shape.
 *
 * Consumer: session state, TUI badges, command handlers, audit logs.
 */
export function buildModeState({
	workMode = "chat",
	runControl = "manual",
	permissionProfile = "restricted",
	modelMode = "smart",
	surface = "tui",
} = {}) {
	return {
		workMode: resolveWorkMode(workMode),
		runControl: resolveRunControlMode(runControl),
		permissionProfile: resolvePermissionProfile(permissionProfile),
		modelMode: resolveModelMode(modelMode),
		surface,
		updatedAt: new Date().toISOString(),
	};
}
