import { CONNECTOR_SCOPE_ORDER } from '../../types/connector/index.js';
import { getRootLogger } from '../../utils/logger.js';
function scopeKey(scope, scopeId, connectorId) {
    return `${scope}:${scopeId}:${connectorId}`;
}
export class ScopedConnectorRegistry {
    configs = new Map();
    log;
    constructor() {
        this.log = getRootLogger().child({ component: 'ScopedConnectorRegistry' });
    }
    set(config) {
        const key = scopeKey(config.scope.scope, config.scope.scopeId, config.connectorId);
        this.configs.set(key, config);
        this.log.info(`Scoped config set: ${key}`);
    }
    remove(scope, connectorId) {
        const key = scopeKey(scope.scope, scope.scopeId, connectorId);
        const removed = this.configs.delete(key);
        if (removed) {
            this.log.info(`Scoped config removed: ${key}`);
        }
        return removed;
    }
    getAt(scope, connectorId) {
        return this.configs.get(scopeKey(scope.scope, scope.scopeId, connectorId));
    }
    resolve(connectorId, chain) {
        const layers = [];
        for (const scope of CONNECTOR_SCOPE_ORDER) {
            const scopeId = chain[scope];
            if (!scopeId)
                continue;
            const config = this.configs.get(scopeKey(scope, scopeId, connectorId));
            if (config) {
                layers.push(config);
            }
        }
        if (layers.length === 0)
            return undefined;
        return this.mergeLayers(connectorId, layers);
    }
    listForConnector(connectorId) {
        const results = [];
        for (const config of this.configs.values()) {
            if (config.connectorId === connectorId) {
                results.push(config);
            }
        }
        return results;
    }
    listAtScope(scope) {
        const prefix = `${scope.scope}:${scope.scopeId}:`;
        const results = [];
        for (const [key, config] of this.configs.entries()) {
            if (key.startsWith(prefix)) {
                results.push(config);
            }
        }
        return results;
    }
    mergeLayers(connectorId, layers) {
        let mergedOptions = {};
        let mergedAuth;
        let mergedEnabled = true;
        let mergedPartialConfig = {};
        const resolvedFrom = [];
        for (const layer of layers) {
            resolvedFrom.push(layer.scope);
            if (layer.options) {
                mergedOptions = { ...mergedOptions, ...layer.options };
            }
            if (layer.auth !== undefined) {
                mergedAuth = layer.auth;
            }
            if (layer.enabled !== undefined) {
                mergedEnabled = layer.enabled;
            }
            if (layer.config) {
                mergedPartialConfig = { ...mergedPartialConfig, ...layer.config };
            }
        }
        const config = {
            connectorId,
            name: mergedPartialConfig.name ?? connectorId,
            auth: mergedAuth ?? mergedPartialConfig.auth,
            options: mergedOptions,
        };
        return {
            connectorId,
            config,
            auth: mergedAuth,
            enabled: mergedEnabled,
            options: mergedOptions,
            resolvedFrom,
        };
    }
}
//# sourceMappingURL=scoped.js.map