import { UokGateRunner } from "./gate-runner.js";

/**
 * UokGateRegistry — process-wide registry of UokGate objects.
 *
 * Purpose: replace the 8+ ad-hoc `new UokGateRunner()` call sites with a
 * single registered set per ADR-0075. Consumers register gates at module
 * load time (static imports + register call); call sites then ask the
 * registry to execute by gate id, with a ctxFactory that knows how to
 * build the per-call ctx.
 */
export class UokGateRegistry {
	constructor() {
		this._runner = new UokGateRunner();
		this._registered = new Map(); // id -> {gate, ctxFactory?}
	}

	register(gate, ctxFactory) {
		if (!gate || typeof gate.id !== "string") {
			throw new Error("UokGateRegistry.register: gate.id required");
		}
		this._registered.set(gate.id, { gate, ctxFactory });
		this._runner.register(gate);
		return this;
	}

	has(gateId) {
		return this._registered.has(gateId);
	}
	list() {
		return Array.from(this._registered.keys());
	}

	async run(gateId, ctxOverride = {}) {
		const entry = this._registered.get(gateId);
		if (!entry)
			throw new Error(
				`UokGateRegistry: no gate registered with id="${gateId}"`,
			);
		const baseCtx = entry.ctxFactory ? await entry.ctxFactory() : {};
		return this._runner.run(gateId, { ...baseCtx, ...ctxOverride });
	}
}

// Process singleton
let _instance = null;
export function getGateRegistry() {
	if (!_instance) _instance = new UokGateRegistry();
	return _instance;
}
export function resetGateRegistryForTests() {
	_instance = null;
}
