"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports._buildPoolRebalanceRoot = exports.getEndBlockBuffers = exports.prettyPrintV3SpokePoolEvents = exports.getRefundsFromBundle = void 0;
var tslib_1 = require("tslib");
var assert_1 = tslib_1.__importDefault(require("assert"));
var utils_1 = require("../../../utils");
var PoolRebalanceUtils_1 = require("./PoolRebalanceUtils");
var MerkleTreeUtils_1 = require("./MerkleTreeUtils");
function getRefundsFromBundle(bundleFillsV3, expiredDepositsToRefundV3) {
    var combinedRefunds = {};
    Object.entries(bundleFillsV3).forEach(function (_a) {
        var _b;
        var repaymentChainId = _a[0], fillsForChain = _a[1];
        (_b = combinedRefunds[repaymentChainId]) !== null && _b !== void 0 ? _b : (combinedRefunds[repaymentChainId] = {});
        Object.entries(fillsForChain).forEach(function (_a) {
            var l2TokenAddress = _a[0], refunds = _a[1].refunds;
            if (refunds === undefined) {
                return;
            }
            var refundsShallowCopy = tslib_1.__assign({}, refunds);
            if (combinedRefunds[repaymentChainId][l2TokenAddress] === undefined) {
                combinedRefunds[repaymentChainId][l2TokenAddress] = refundsShallowCopy;
            }
            else {
                combinedRefunds[repaymentChainId][l2TokenAddress] = tslib_1.__assign(tslib_1.__assign({}, combinedRefunds[repaymentChainId][l2TokenAddress]), refundsShallowCopy);
            }
        });
    });
    Object.entries(expiredDepositsToRefundV3).forEach(function (_a) {
        var _b;
        var originChainId = _a[0], depositsForChain = _a[1];
        (_b = combinedRefunds[originChainId]) !== null && _b !== void 0 ? _b : (combinedRefunds[originChainId] = {});
        Object.entries(depositsForChain).forEach(function (_a) {
            var l2TokenAddress = _a[0], deposits = _a[1];
            deposits.forEach(function (deposit) {
                var _a;
                if (combinedRefunds[originChainId][l2TokenAddress] === undefined) {
                    combinedRefunds[originChainId][l2TokenAddress] = (_a = {}, _a[deposit.depositor.toBytes32()] = deposit.inputAmount, _a);
                }
                else {
                    var existingRefundAmount = combinedRefunds[originChainId][l2TokenAddress][deposit.depositor.toBytes32()];
                    combinedRefunds[originChainId][l2TokenAddress][deposit.depositor.toBytes32()] = deposit.inputAmount.add(existingRefundAmount !== null && existingRefundAmount !== void 0 ? existingRefundAmount : utils_1.bnZero);
                }
            });
        });
    });
    return combinedRefunds;
}
exports.getRefundsFromBundle = getRefundsFromBundle;
function prettyPrintV3SpokePoolEvents(bundleDepositsV3, bundleFillsV3, bundleSlowFillsV3, expiredDepositsToRefundV3, unexecutableSlowFills) {
    return {
        bundleDepositsV3: (0, utils_1.count2DDictionaryValues)(bundleDepositsV3),
        bundleFillsV3: (0, utils_1.count3DDictionaryValues)(bundleFillsV3, "fills"),
        bundleSlowFillsV3: (0, utils_1.count2DDictionaryValues)(bundleSlowFillsV3),
        expiredDepositsToRefundV3: (0, utils_1.count2DDictionaryValues)(expiredDepositsToRefundV3),
        unexecutableSlowFills: (0, utils_1.count2DDictionaryValues)(unexecutableSlowFills),
    };
}
exports.prettyPrintV3SpokePoolEvents = prettyPrintV3SpokePoolEvents;
function getEndBlockBuffers(chainIdListForBundleEvaluationBlockNumbers, blockRangeEndBlockBuffer) {
    return chainIdListForBundleEvaluationBlockNumbers.map(function (chainId) { var _a; return (_a = blockRangeEndBlockBuffer[chainId]) !== null && _a !== void 0 ? _a : 0; });
}
exports.getEndBlockBuffers = getEndBlockBuffers;
function _buildPoolRebalanceRoot(latestMainnetBlock, mainnetBundleEndBlock, bundleV3Deposits, bundleFillsV3, bundleSlowFillsV3, unexecutableSlowFills, expiredDepositsToRefundV3, clients, maxL1TokenCountOverride) {
    var runningBalances = {};
    var realizedLpFees = {};
    var chainWithRefundsOnly = new Set();
    Object.entries(bundleFillsV3).forEach(function (_a) {
        var _repaymentChainId = _a[0], fillsForChain = _a[1];
        var repaymentChainId = Number(_repaymentChainId);
        Object.entries(fillsForChain).forEach(function (_a) {
            var l2TokenAddress = _a[0], _b = _a[1], totalRealizedLpFee = _b.realizedLpFees, totalRefundAmount = _b.totalRefundAmount;
            if (!clients.hubPoolClient.l2TokenHasPoolRebalanceRoute((0, utils_1.toAddressType)(l2TokenAddress, repaymentChainId), repaymentChainId, mainnetBundleEndBlock)) {
                chainWithRefundsOnly.add(repaymentChainId);
                return;
            }
            var l1Token = clients.hubPoolClient.getL1TokenForL2TokenAtBlock((0, utils_1.toAddressType)(l2TokenAddress, repaymentChainId), repaymentChainId, mainnetBundleEndBlock);
            var l1TokenAddr = l1Token.toNative();
            (0, assert_1.default)(l1Token.isEVM(), "Expected an EVM address: ".concat(l1TokenAddr));
            (0, PoolRebalanceUtils_1.updateRunningBalance)(runningBalances, repaymentChainId, l1TokenAddr, totalRefundAmount);
            (0, PoolRebalanceUtils_1.updateRunningBalance)(realizedLpFees, repaymentChainId, l1TokenAddr, totalRealizedLpFee);
        });
    });
    Object.entries(bundleSlowFillsV3).forEach(function (_a) {
        var _destinationChainId = _a[0], depositsForChain = _a[1];
        var destinationChainId = Number(_destinationChainId);
        Object.entries(depositsForChain).forEach(function (_a) {
            var outputToken = _a[0], deposits = _a[1];
            deposits.forEach(function (deposit) {
                var l1TokenCounterpart = clients.hubPoolClient.getL1TokenForL2TokenAtBlock((0, utils_1.toAddressType)(outputToken, destinationChainId), destinationChainId, mainnetBundleEndBlock);
                var lpFee = deposit.lpFeePct.mul(deposit.inputAmount).div(utils_1.fixedPointAdjustment);
                (0, PoolRebalanceUtils_1.updateRunningBalance)(runningBalances, destinationChainId, l1TokenCounterpart.toEvmAddress(), deposit.inputAmount.sub(lpFee));
            });
        });
    });
    Object.entries(unexecutableSlowFills).forEach(function (_a) {
        var _destinationChainId = _a[0], slowFilledDepositsForChain = _a[1];
        var destinationChainId = Number(_destinationChainId);
        Object.entries(slowFilledDepositsForChain).forEach(function (_a) {
            var outputToken = _a[0], slowFilledDeposits = _a[1];
            slowFilledDeposits.forEach(function (deposit) {
                var l1TokenCounterpart = clients.hubPoolClient.getL1TokenForL2TokenAtBlock((0, utils_1.toAddressType)(outputToken, destinationChainId), destinationChainId, mainnetBundleEndBlock);
                var lpFee = deposit.lpFeePct.mul(deposit.inputAmount).div(utils_1.fixedPointAdjustment);
                (0, PoolRebalanceUtils_1.updateRunningBalance)(runningBalances, destinationChainId, l1TokenCounterpart.toEvmAddress(), lpFee.sub(deposit.inputAmount));
            });
        });
    });
    Object.entries(bundleV3Deposits).forEach(function (_a) {
        var depositsForChain = _a[1];
        Object.entries(depositsForChain).forEach(function (_a) {
            var deposits = _a[1];
            deposits.forEach(function (deposit) {
                if (!clients.hubPoolClient.l2TokenHasPoolRebalanceRoute(deposit.inputToken, deposit.originChainId, mainnetBundleEndBlock)) {
                    return;
                }
                (0, PoolRebalanceUtils_1.updateRunningBalanceForDeposit)(runningBalances, clients.hubPoolClient, deposit, deposit.inputAmount.mul(-1), mainnetBundleEndBlock);
            });
        });
    });
    Object.entries(expiredDepositsToRefundV3).forEach(function (_a) {
        var _originChainId = _a[0], depositsForChain = _a[1];
        var originChainId = Number(_originChainId);
        Object.entries(depositsForChain).forEach(function (_a) {
            var inputToken = _a[0], deposits = _a[1];
            deposits.forEach(function (deposit) {
                if (!clients.hubPoolClient.l2TokenHasPoolRebalanceRoute(deposit.inputToken, deposit.originChainId, mainnetBundleEndBlock)) {
                    chainWithRefundsOnly.add(deposit.originChainId);
                    return;
                }
                var l1TokenCounterpart = clients.hubPoolClient.getL1TokenForL2TokenAtBlock((0, utils_1.toAddressType)(inputToken, originChainId), originChainId, mainnetBundleEndBlock);
                (0, PoolRebalanceUtils_1.updateRunningBalance)(runningBalances, originChainId, l1TokenCounterpart.toEvmAddress(), deposit.inputAmount);
            });
        });
    });
    (0, PoolRebalanceUtils_1.addLastRunningBalance)(latestMainnetBlock, runningBalances, clients.hubPoolClient);
    var leaves = (0, PoolRebalanceUtils_1.constructPoolRebalanceLeaves)(mainnetBundleEndBlock, runningBalances, realizedLpFees, Array.from(chainWithRefundsOnly).filter(function (chainId) { return !Object.keys(runningBalances).includes(chainId.toString()); }), clients.configStoreClient, maxL1TokenCountOverride);
    return {
        runningBalances: runningBalances,
        realizedLpFees: realizedLpFees,
        leaves: leaves,
        tree: (0, MerkleTreeUtils_1.buildPoolRebalanceLeafTree)(leaves),
    };
}
exports._buildPoolRebalanceRoot = _buildPoolRebalanceRoot;
//# sourceMappingURL=DataworkerUtils.js.map