var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var BlockchainProviderModule_1;
import { v4 as uuidv4 } from 'uuid';
import { Module, Logger } from '@nestjs/common';
import { BlockchainProviderService, NetworkConnectionManager, MempoolConnectionManager, } from '../../core/blockchain-provider';
import { createProvider } from '../../core/blockchain-provider/providers';
let BlockchainProviderModule = BlockchainProviderModule_1 = class BlockchainProviderModule {
    static async forRootAsync(options) {
        const { networkProviders, mempoolProviders, isGlobal, rateLimits, network } = options;
        // Validate: WS URL requires a paired RPC URL.
        // WS handles real-time block subscriptions; RPC handles block/receipt fetching.
        for (const conn of networkProviders.connections) {
            if (conn.wsUrl && !conn.httpUrl) {
                throw new Error(`BlockchainProviderModule: wsUrl "${conn.wsUrl}" is configured without a paired httpUrl. ` +
                    'Each WS connection must have a corresponding RPC HTTP URL for block fetching.');
            }
        }
        const buildNetworkProviders = () => networkProviders.connections.map((conn, i) => createProvider({
            type: networkProviders.type,
            uniqName: `network_${networkProviders.type}_${i + 1}_${uuidv4()}`,
            httpUrl: conn.httpUrl,
            wsUrl: conn.wsUrl,
            rateLimits,
            network,
        }));
        const buildMempoolProviders = () => mempoolProviders
            ? mempoolProviders.connections
                .filter((conn) => Boolean(conn.httpUrl || conn.wsUrl))
                .map((conn, i) => createProvider({
                type: mempoolProviders.type,
                uniqName: `mempool_${mempoolProviders.type}_${i + 1}_${uuidv4()}`,
                httpUrl: conn.httpUrl || conn.wsUrl,
                wsUrl: conn.wsUrl,
                rateLimits,
                network,
            }))
            : [];
        const providers = [
            {
                provide: NetworkConnectionManager,
                useFactory: async () => {
                    const providerInstances = buildNetworkProviders();
                    const manager = new NetworkConnectionManager({
                        providers: providerInstances,
                        logger: new Logger(NetworkConnectionManager.name),
                    });
                    await manager.initialize();
                    return manager;
                },
                inject: [],
            },
            {
                provide: MempoolConnectionManager,
                useFactory: async () => {
                    const providerInstances = buildMempoolProviders();
                    const manager = new MempoolConnectionManager({
                        providers: providerInstances,
                        logger: new Logger(MempoolConnectionManager.name),
                    });
                    await manager.initialize();
                    return manager;
                },
                inject: [],
            },
            {
                provide: BlockchainProviderService,
                useFactory: (networkManager, mempoolManager) => new BlockchainProviderService(networkManager, mempoolManager, network),
                inject: [NetworkConnectionManager, MempoolConnectionManager],
            },
        ];
        return {
            module: BlockchainProviderModule_1,
            global: isGlobal || false,
            imports: [],
            providers,
            exports: [BlockchainProviderService],
        };
    }
};
BlockchainProviderModule = BlockchainProviderModule_1 = __decorate([
    Module({})
], BlockchainProviderModule);
export { BlockchainProviderModule };
