import { resolveAgentId, parseAgentSpecifier } from "@poe-code/agent-defs";
export function createServiceRegistry() {
    const canonicalAdapters = new Map();
    const nameToCanonical = new Map();
    const listProviderKeys = (adapter) => {
        const keys = [adapter.name];
        for (const alias of adapter.aliases ?? []) {
            if (typeof alias !== "string") {
                continue;
            }
            const normalized = alias.trim();
            if (normalized.length === 0) {
                continue;
            }
            if (!keys.includes(normalized)) {
                keys.push(normalized);
            }
        }
        return keys;
    };
    const register = (adapter) => {
        if (canonicalAdapters.has(adapter.name)) {
            throw new Error(`Provider "${adapter.name}" is already registered.`);
        }
        const keys = listProviderKeys(adapter);
        for (const key of keys) {
            if (nameToCanonical.has(key)) {
                throw new Error(`Provider "${key}" is already registered.`);
            }
        }
        canonicalAdapters.set(adapter.name, adapter);
        for (const key of keys) {
            nameToCanonical.set(key, adapter.name);
        }
    };
    const discover = (candidates) => {
        for (const candidate of candidates) {
            if (canonicalAdapters.has(candidate.name)) {
                continue;
            }
            const keys = listProviderKeys(candidate);
            if (keys.some((key) => nameToCanonical.has(key))) {
                continue;
            }
            canonicalAdapters.set(candidate.name, candidate);
            for (const key of keys) {
                nameToCanonical.set(key, candidate.name);
            }
        }
    };
    const resolveCanonicalName = (name) => {
        const direct = nameToCanonical.get(name);
        if (direct) {
            return direct;
        }
        const { agent } = parseAgentSpecifier(name);
        const resolvedAgent = resolveAgentId(agent);
        if (!resolvedAgent) {
            return undefined;
        }
        return nameToCanonical.get(resolvedAgent);
    };
    const get = (name) => {
        const canonicalName = resolveCanonicalName(name);
        if (!canonicalName) {
            return undefined;
        }
        return canonicalAdapters.get(canonicalName);
    };
    const require = (name) => {
        const adapter = get(name);
        if (!adapter) {
            throw new Error(`Unknown provider "${name}".`);
        }
        return adapter;
    };
    const list = () => Array.from(canonicalAdapters.values());
    const invoke = async (serviceName, operation, runner) => {
        const adapter = require(serviceName);
        return await runner(adapter);
    };
    return { register, discover, get, require, list, invoke };
}
//# sourceMappingURL=service-registry.js.map