/**
 * Adaptive Verification Policy
 *
 * Purpose: close the self-improvement loop by reading OutcomeLearningGate
 * findings and adjusting verification retry policy (verification_max_retries,
 * verification_auto_fix) based on recent failure patterns.
 *
 * Consumer: auto-verification.js after OutcomeLearningGate runs.
 */
import { saveFile } from "../files.js";
import {
	getProjectSFPreferencesPath,
	loadProjectSFPreferences,
} from "../preferences.js";
import { serializePreferencesToFrontmatter } from "../preferences-serializer.js";
import { readTraceEvents } from "./trace-writer.js";

const MIN_SAMPLE_SIZE = 5;
const LOOKBACK_HOURS = 24;
const HIGH_FAILURE_THRESHOLD = 0.6;
const LOW_FAILURE_THRESHOLD = 0.3;
const MAX_RETRIES_CEILING = 3;

/**
 * Compute an adaptive verification policy based on OutcomeLearningGate
 * trace events from the last 24 hours.
 *
 * @param {string} basePath — project base path
 * @param {object} currentPrefs — current effective preferences subset
 * @param {Array<object>} [overrideEvents] — optional injected events for testing
 * @returns {object|null} — { verification_max_retries, verification_auto_fix } or null if no change
 */
export function computeAdaptiveVerificationPolicy(
	basePath,
	currentPrefs,
	overrideEvents,
) {
	const events =
		overrideEvents ??
		readTraceEvents(basePath, "gate_run", LOOKBACK_HOURS).filter(
			(e) => e.gateId === "outcome-learning",
		);

	if (events.length < MIN_SAMPLE_SIZE) {
		return null;
	}

	const currentMaxRetries = currentPrefs?.verification_max_retries ?? 2;
	const currentAutoFix = currentPrefs?.verification_auto_fix ?? true;

	let newMaxRetries = currentMaxRetries;
	let newAutoFix = currentAutoFix;
	let changed = false;

	// Count failures by failureClass
	const byClass = new Map();
	let totalFails = 0;
	for (const e of events) {
		if (e.outcome === "fail") {
			totalFails++;
			const fc = e.failureClass || "unknown";
			byClass.set(fc, (byClass.get(fc) || 0) + 1);
		}
	}

	// High failure rate (>60%) for verification/artifact/execution → reduce retries, disable auto-fix
	const highImpactClasses = ["verification", "artifact", "execution"];
	for (const fc of highImpactClasses) {
		const count = byClass.get(fc) || 0;
		const rate = count / events.length;
		if (rate > HIGH_FAILURE_THRESHOLD) {
			newMaxRetries = 1;
			newAutoFix = false;
			changed = true;
		}
	}

	// Low overall failure rate (<30%) and all passing → optionally increase retries
	const overallFailureRate = totalFails / events.length;
	if (overallFailureRate < LOW_FAILURE_THRESHOLD && totalFails === 0) {
		const bumped = Math.min(currentMaxRetries + 1, MAX_RETRIES_CEILING);
		if (bumped !== currentMaxRetries) {
			newMaxRetries = bumped;
			changed = true;
		}
	}

	if (!changed) {
		return null;
	}

	return {
		verification_max_retries: newMaxRetries,
		verification_auto_fix: newAutoFix,
	};
}

/**
 * Apply an adaptive policy to project preferences.
 *
 * @param {string} basePath — project base path
 * @param {object} policy — { verification_max_retries, verification_auto_fix }
 * @returns {boolean} — true if preferences were written
 */
export async function applyAdaptiveVerificationPolicy(_basePath, policy) {
	const path = getProjectSFPreferencesPath();
	const existing = loadProjectSFPreferences();
	const prefs = existing?.preferences
		? { ...existing.preferences }
		: { version: 1 };

	prefs.verification_max_retries = policy.verification_max_retries;
	prefs.verification_auto_fix = policy.verification_auto_fix;

	const yaml = serializePreferencesToFrontmatter(prefs);
	await saveFile(path, yaml);
	return true;
}
