/**
 * production-plateau.js — detect long autonomous runs with no productive delta.
 *
 * Purpose: stop SF from mistaking a long-running loop for useful work when the
 * same unit keeps cycling without artifact, status, or evidence progress.
 *
 * Consumer: M048/S03 Wiggums detector sweep.
 */
export const UNCHANGED_THRESHOLD = 15;
export const TOTAL_THRESHOLD = 40;

/**
 * Detect production plateau from aggregate unit metrics.
 *
 * Purpose: provide a coarse-grained safety signal for runs that are not fast
 * crashes but still fail to produce useful state over many cycles.
 *
 * Consumer: periodic-runner.js default detector list.
 */
export function detectProductionPlateau(unitMetrics, ctx = {}, options = {}) {
	if (!unitMetrics || typeof unitMetrics !== "object") {
		return { stuck: false, reason: "missing-metrics", signature: {} };
	}
	const unchangedThreshold = options.unchangedThreshold ?? UNCHANGED_THRESHOLD;
	const totalThreshold = options.totalThreshold ?? TOTAL_THRESHOLD;
	const totalCycles = numberAt(unitMetrics, "totalCycles", "total_cycles");
	const unchangedCycles = numberAt(
		unitMetrics,
		"unchangedCycles",
		"unchanged_cycles",
	);
	const productiveCycles = numberAt(
		unitMetrics,
		"productiveCycles",
		"productive_cycles",
		"completedCycles",
		"completed_cycles",
	);
	const artifactDelta = numberAt(
		unitMetrics,
		"artifactDelta",
		"artifact_delta",
		"filesChanged",
		"files_changed",
	);
	const statusDelta = numberAt(unitMetrics, "statusDelta", "status_delta");

	if (productiveCycles > 0 || artifactDelta > 0 || statusDelta > 0) {
		return { stuck: false, reason: "", signature: { productiveCycles } };
	}
	if (unchangedCycles >= unchangedThreshold && totalCycles >= totalThreshold) {
		return {
			stuck: true,
			reason: "production-plateau",
			signature: {
				unitId: ctx.unitId ?? unitMetrics.unitId ?? unitMetrics.unit_id ?? null,
				totalCycles,
				unchangedCycles,
				unchangedThreshold,
				totalThreshold,
			},
		};
	}
	return {
		stuck: false,
		reason: "",
		signature: { totalCycles, unchangedCycles },
	};
}

/**
 * Run the production plateau detector as a UOK verification gate.
 *
 * Purpose: make long-run no-progress signals available to the common gate
 * runner without changing detector callers.
 *
 * Consumer: detector gate registry and periodicDetectorSweepGate.
 */
export const productionPlateauGate = {
	id: "production-plateau",
	type: "verification",
	async execute(ctx = {}) {
		const result = detectProductionPlateau(ctx.unitMetrics, ctx, ctx.options);
		if (result.stuck) {
			return {
				outcome: "fail",
				failureClass: "verification",
				rationale: result.reason,
				findings: result.signature,
			};
		}
		return {
			outcome: "pass",
			failureClass: null,
			rationale: result.reason || "no production plateau",
		};
	},
};

function numberAt(source, ...keys) {
	for (const key of keys) {
		const value = source?.[key];
		if (typeof value === "number" && Number.isFinite(value)) return value;
	}
	return 0;
}
