"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RateLimitedSolanaRpcFactory = void 0;
var tslib_1 = require("tslib");
var async_1 = require("async");
var winston_1 = tslib_1.__importDefault(require("winston"));
var baseRpcFactories_1 = require("./baseRpcFactories");
var defaultRpcFactory_1 = require("./defaultRpcFactory");
var utils_1 = require("../../utils");
var RateLimitedSolanaRpcFactory = (function (_super) {
    tslib_1.__extends(RateLimitedSolanaRpcFactory, _super);
    function RateLimitedSolanaRpcFactory(maxConcurrency, pctRpcCallsLogged, logger) {
        if (logger === void 0) { logger = winston_1.default.createLogger({
            transports: [new winston_1.default.transports.Console()],
        }); }
        var defaultConstructorParams = [];
        for (var _i = 3; _i < arguments.length; _i++) {
            defaultConstructorParams[_i - 3] = arguments[_i];
        }
        var _this = _super.apply(this, defaultConstructorParams) || this;
        _this.pctRpcCallsLogged = pctRpcCallsLogged;
        _this.logger = logger;
        _this.defaultTransport = new (defaultRpcFactory_1.SolanaDefaultRpcFactory.bind.apply(defaultRpcFactory_1.SolanaDefaultRpcFactory, tslib_1.__spreadArray([void 0], defaultConstructorParams, false)))().createTransport();
        _this.queue = (0, async_1.queue)(function (_a, callback) {
            var rpcArgs = _a.rpcArgs, resolve = _a.resolve, reject = _a.reject;
            return tslib_1.__awaiter(_this, void 0, void 0, function () {
                return tslib_1.__generator(this, function (_b) {
                    switch (_b.label) {
                        case 0: return [4, this.wrapSendWithLog.apply(this, rpcArgs).then(resolve)
                                .catch(reject)];
                        case 1:
                            _b.sent();
                            callback();
                            return [2];
                    }
                });
            });
        }, maxConcurrency);
        return _this;
    }
    RateLimitedSolanaRpcFactory.prototype.wrapSendWithLog = function () {
        var rpcArgs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            rpcArgs[_i] = arguments[_i];
        }
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var payload, loggerArgs, startTime, result, elapsedTimeS, error_1, elapsedTimeS;
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!(this.pctRpcCallsLogged <= 0 || Math.random() > this.pctRpcCallsLogged / 100)) return [3, 2];
                        return [4, this.defaultTransport.apply(this, rpcArgs)];
                    case 1: return [2, _a.sent()];
                    case 2:
                        payload = rpcArgs[0].payload;
                        loggerArgs = {
                            at: "SolanaProviderUtils",
                            message: "Solana provider response sample",
                            provider: (0, utils_1.getOriginFromURL)(this.clusterUrl),
                            method: payload.method,
                            params: payload.params,
                            chainId: this.chainId,
                            datadog: true,
                        };
                        startTime = performance.now();
                        _a.label = 3;
                    case 3:
                        _a.trys.push([3, 5, , 6]);
                        return [4, this.defaultTransport.apply(this, rpcArgs)];
                    case 4:
                        result = _a.sent();
                        elapsedTimeS = (performance.now() - startTime) / 1000;
                        this.logger.debug(tslib_1.__assign(tslib_1.__assign({}, loggerArgs), { success: true, timeElapsed: elapsedTimeS }));
                        return [2, result];
                    case 5:
                        error_1 = _a.sent();
                        elapsedTimeS = (performance.now() - startTime) / 1000;
                        this.logger.debug(tslib_1.__assign(tslib_1.__assign({}, loggerArgs), { success: false, timeElapsed: elapsedTimeS }));
                        throw error_1;
                    case 6: return [2];
                }
            });
        });
    };
    RateLimitedSolanaRpcFactory.prototype.createTransport = function () {
        var _this = this;
        return function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return new Promise(function (resolve, reject) {
                var task = {
                    rpcArgs: args,
                    resolve: resolve,
                    reject: reject,
                };
                void _this.queue.push(task);
            });
        };
    };
    return RateLimitedSolanaRpcFactory;
}(baseRpcFactories_1.SolanaClusterRpcFactory));
exports.RateLimitedSolanaRpcFactory = RateLimitedSolanaRpcFactory;
//# sourceMappingURL=rateLimitedRpcFactory.js.map