/**
 * UOK Contract Types
 *
 * Purpose: provide a single source of truth for gate interfaces so that
 * implementations, consumers, and tests share the same structural expectations.
 *
 * Consumer: all UOK gates, gate-runner, and extension verification flows.
 */

/**
 * @typedef {Object} UokContext
 * @property {string} basePath — project root path
 * @property {string} [traceId] — distributed trace identifier
 * @property {string} [turnId] — current turn identifier
 * @property {string} [unitType] — e.g. "execute-task", "complete-slice"
 * @property {string} [unitId] — e.g. "M001/S01/T01"
 * @property {string} [milestoneId]
 * @property {string} [sliceId]
 * @property {string} [taskId]
 * @property {string} [modelId] — LLM model identifier
 * @property {string} [provider] — LLM provider name
 * @property {"manual"|"assisted"|"autonomous"} [runControl] — who advances the flow
 * @property {"restricted"|"normal"|"trusted"|"unrestricted"} [permissionProfile] — tool/file/network trust posture
 * @property {number} [iteration] — current retry/dispatch iteration
 * @property {number} [tokenCount] — tokens consumed this turn
 * @property {number} [costUsd] — estimated cost this turn
 * @property {number} [durationMs] — turn duration
 * @property {boolean} [succeeded] — whether the unit succeeded
 */

/**
 * @typedef {Object} GateResult
 * @property {"pass"|"fail"|"retry"|"manual-attention"} outcome
 * @property {string} [failureClass] — "policy" | "verification" | "execution" | "artifact" | "git" | "timeout" | "input" | "closeout" | "manual-attention" | "unknown"
 * @property {string} rationale — human-readable explanation
 * @property {string} [findings] — structured output (errors, diffs, etc.)
 * @property {string} [recommendation] — actionable next step
 */

/**
 * @typedef {Object} Gate
 * @property {string} id — unique gate identifier
 * @property {string} type — "security" | "policy" | "verification" | "learning" | "chaos"
 * @property {(ctx: UokContext, attempt: number) => Promise<GateResult>|GateResult} execute
 */

/**
 * @typedef {Object} MessageBusMessage
 * @property {string} id — unique message identifier
 * @property {string} from — sender agent id
 * @property {string} to — recipient agent id
 * @property {string} body — message payload
 * @property {Record<string, unknown>} [metadata]
 * @property {string} sentAt — ISO timestamp
 * @property {string} [receivedAt] — ISO timestamp
 * @property {boolean} [read] — whether the message has been read
 */

/**
 * @typedef {Object} MessageBusOptions
 * @property {string} basePath — project root for durable storage
 * @property {number} [retentionDays] — how long to keep messages (default 7)
 * @property {number} [maxInboxSize] — per-agent inbox limit (default 1000)
 */

/**
 * @typedef {Object} ChaosMonkeyOptions
 * @property {number} [latencyProbability] — chance to inject latency (default 0.05)
 * @property {number} [partialFailureProbability] — chance to throw non-fatal error (default 0.03)
 * @property {number} [diskStressProbability] — chance to write temp stress file (default 0.01)
 * @property {number} [maxLatencyMs] — max injected latency (default 5000)
 * @property {boolean} [active] — whether monkey is enabled (default false)
 */

/**
 * @typedef {Object} CostGuardOptions
 * @property {number} [maxUsdPerUnit] — abort threshold for a single unit (default 5.0)
 * @property {number} [maxUsdPerHour] — abort threshold for rolling 1h window (default 20.0)
 * @property {number} [highTierFailureThreshold] — consecutive high-tier failures before block (default 2)
 */

/**
 * @typedef {Object} MultiPackageOptions
 * @property {number} [timeoutMs] — timeout for verification commands (default 120000)
 * @property {string[]} [additionalChecks] — extra npm scripts to run (default ["typecheck"])
 */

/**
 * @typedef {Object} OutcomeLearningOptions
 * @property {number} [minSampleSize] — minimum outcomes before pattern detection (default 3)
 * @property {number} [failureRateThreshold] — failure rate that triggers recommendation (default 0.6)
 * @property {number} [lookbackHours] — how far back to query (default 168)
 */

/**
 * Validate that a value conforms to the Gate interface.
 *
 * Purpose: catch registration-time mistakes (missing id, non-function execute)
 * instead of deferring the failure to the first run() call.
 *
 * Consumer: UokGateRunner.register and gate factory tests.
 *
 * @param {unknown} value
 * @returns {{ valid: true } | { valid: false; reason: string }}
 */
export function validateGate(value) {
	if (value == null || typeof value !== "object") {
		return { valid: false, reason: "Gate must be an object" };
	}
	const gate = /** @type {Record<string, unknown>} */ (value);
	if (typeof gate.id !== "string" || gate.id.length === 0) {
		return { valid: false, reason: "Gate.id must be a non-empty string" };
	}
	if (typeof gate.type !== "string" || gate.type.length === 0) {
		return { valid: false, reason: "Gate.type must be a non-empty string" };
	}
	if (typeof gate.execute !== "function") {
		return { valid: false, reason: "Gate.execute must be a function" };
	}
	return { valid: true };
}
