"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseConnectionManager = void 0;
/**
 * Shared provider registry/connection lifecycle for EVM managers.
 * Network/mempool managers decide their own failover and availability policies.
 */
class BaseConnectionManager {
    moduleName = 'blockchain-provider';
    providers = new Map();
    logger;
    connected = new Set();
    constructor(options) {
        this.logger = options.logger;
        for (const provider of options.providers) {
            const name = provider.uniqName;
            if (this.providers.has(name)) {
                throw new Error(`A provider with the name "${name}" has already been added.`);
            }
            this.providers.set(name, provider);
            this.logger.verbose?.('Provider registered', {
                module: this.moduleName,
                args: { providerName: name, providerType: provider.type },
            });
        }
    }
    get allProviders() {
        return Array.from(this.providers.values());
    }
    async ensureConnected(provider) {
        if (this.connected.has(provider.uniqName))
            return true;
        try {
            await provider.connect();
            this.connected.add(provider.uniqName);
            return true;
        }
        catch (error) {
            this.logger.verbose?.('Provider connection attempt failed', {
                module: this.moduleName,
                args: { providerName: provider.uniqName, action: 'connect', error: error.message },
            });
            return false;
        }
    }
    async ensureConnectedAll() {
        const connected = [];
        const failed = [];
        for (const provider of this.providers.values()) {
            const ok = await this.ensureConnected(provider);
            if (ok)
                connected.push(provider);
            else
                failed.push(provider);
        }
        return { connected, failed };
    }
    async destroy() {
        for (const provider of this.providers.values()) {
            try {
                await provider.disconnect();
            }
            catch (error) {
                this.logger.verbose?.('Error disconnecting provider during cleanup', {
                    module: this.moduleName,
                    args: { providerName: provider.uniqName, action: 'destroy', error },
                });
            }
            finally {
                this.connected.delete(provider.uniqName);
            }
        }
    }
    async getProviderByName(name) {
        const provider = this.providers.get(name);
        if (!provider)
            throw new Error(`Provider with name ${name} not found`);
        return provider;
    }
    async removeProvider(name) {
        const provider = this.providers.get(name);
        if (!provider)
            throw new Error(`Provider with name ${name} not found`);
        try {
            await provider.disconnect();
        }
        finally {
            this.connected.delete(name);
        }
        return this.providers.delete(name);
    }
    getConnectionOptionsForAllProviders() {
        return Array.from(this.providers.values()).map((provider) => provider?.connectionOptions);
    }
}
exports.BaseConnectionManager = BaseConnectionManager;
