"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockHubPoolClient = void 0;
const utils_1 = require("../../utils");
const HubPoolClient_1 = require("../HubPoolClient");
const MockEvents_1 = require("./MockEvents");
const constants_1 = require("../../constants");
const emptyRootBundle = {
    poolRebalanceRoot: "",
    relayerRefundRoot: "",
    slowRelayRoot: "",
    proposer: utils_1.EvmAddress.from(constants_1.ZERO_ADDRESS),
    unclaimedPoolRebalanceLeafCount: 0,
    challengePeriodEndTimestamp: 0,
    bundleEvaluationBlockNumbers: [],
    proposalBlockNumber: undefined,
};
class MockHubPoolClient extends HubPoolClient_1.HubPoolClient {
    rootBundleProposal = emptyRootBundle;
    realizedLpFeePct = utils_1.bnZero;
    realizedLpFeePctOverride = false;
    l1TokensMock = [];
    spokePoolTokens = {};
    eventManager;
    constructor(logger, hubPool, configStoreClient, deploymentBlock = 0, chainId = constants_1.CHAIN_IDs.MAINNET, opts = {}) {
        super(logger, hubPool, configStoreClient, deploymentBlock, chainId);
        this.eventManager = opts.eventManager ?? new MockEvents_1.EventManager(deploymentBlock);
        this.eventManager.addEventSignatures(this.eventSignatures);
    }
    setDefaultRealizedLpFeePct(fee) {
        this.realizedLpFeePct = fee;
        this.realizedLpFeePctOverride = true;
    }
    clearDefaultRealizedLpFeePct() {
        this.realizedLpFeePctOverride = false;
    }
    async computeRealizedLpFeePct(deposit) {
        const { realizedLpFeePct, realizedLpFeePctOverride } = this;
        return realizedLpFeePctOverride
            ? { realizedLpFeePct, quoteBlock: 0 }
            : await super.computeRealizedLpFeePct(deposit);
    }
    async batchComputeRealizedLpFeePct(_deposits) {
        const { realizedLpFeePct, realizedLpFeePctOverride } = this;
        return realizedLpFeePctOverride
            ? _deposits.map(() => {
                return { realizedLpFeePct, quoteBlock: 0 };
            })
            : await super.batchComputeRealizedLpFeePct(_deposits);
    }
    setCrossChainContracts(chainId, contract, blockNumber = 0) {
        (0, utils_1.assign)(this.crossChainContracts, [chainId], [
            {
                spokePool: (0, utils_1.toAddressType)(contract, chainId),
                blockNumber: blockNumber,
                logIndex: 0,
                l2ChainId: chainId,
                txnIndex: 0,
                txnRef: "",
            },
        ]);
    }
    setLatestBlockNumber(blockNumber) {
        this.latestHeightSearched = blockNumber;
    }
    addL1Token(l1Token) {
        this.l1TokensMock.push(l1Token);
    }
    getL1Tokens() {
        return this.l1TokensMock;
    }
    setTokenMapping(l1Token, chainId, l2Token) {
        this.spokePoolTokens[l1Token] ??= {};
        this.spokePoolTokens[l1Token][chainId] = (0, utils_1.toAddressType)(l2Token, chainId);
    }
    l2TokenEnabledForL1TokenAtBlock(l1Token, destinationChainId, hubBlockNumber) {
        if (this.spokePoolTokens[l1Token.toEvmAddress()]?.[destinationChainId]) {
            return true;
        }
        else {
            return super.l2TokenEnabledForL1TokenAtBlock(l1Token, destinationChainId, hubBlockNumber);
        }
    }
    l2TokenHasPoolRebalanceRoute(l2Token, chainId, hubPoolBlock) {
        const l1Token = Object.keys(this.spokePoolTokens).find((l1Token) => this.spokePoolTokens[l1Token]?.[chainId]?.eq(l2Token));
        if (!l1Token) {
            return super.l2TokenHasPoolRebalanceRoute(l2Token, chainId, hubPoolBlock);
        }
        else
            return true;
    }
    deleteTokenMapping(l1Token, chainId) {
        delete this.spokePoolTokens[l1Token]?.[chainId];
    }
    getL1TokenForL2TokenAtBlock(l2Token, chainId, blockNumber) {
        const l1Token = Object.keys(this.spokePoolTokens).find((l1Token) => this.spokePoolTokens[l1Token]?.[chainId]?.eq(l2Token));
        if ((0, utils_1.isDefined)(l1Token)) {
            return utils_1.EvmAddress.from(l1Token);
        }
        else {
            return super.getL1TokenForL2TokenAtBlock(l2Token, chainId, blockNumber);
        }
    }
    getL2TokenForL1TokenAtBlock(l1Token, chainId, blockNumber) {
        const l2Token = this.spokePoolTokens[l1Token.toEvmAddress()]?.[chainId];
        return l2Token ?? super.getL2TokenForL1TokenAtBlock(l1Token, chainId, blockNumber);
    }
    getTokenInfoForL1Token(l1Token) {
        return this.l1TokensMock.find((token) => token.address.eq(l1Token));
    }
    _update(eventNames) {
        const latestBlockSearched = this.eventManager.blockNumber;
        const currentTime = Math.floor(Date.now() / 1000);
        const _events = eventNames.map(() => []);
        this.eventManager
            .getEvents()
            .flat()
            .forEach((event) => {
            const idx = eventNames.indexOf(event.event);
            if (idx !== -1) {
                _events[idx].push(event);
            }
        });
        const events = Object.fromEntries(eventNames.map((eventName, idx) => [eventName, _events[idx]]));
        return Promise.resolve({
            success: true,
            currentTime,
            latestBlockSearched,
            pendingRootBundleProposal: this.rootBundleProposal,
            events,
            searchEndBlock: this.eventSearchConfig.to || latestBlockSearched,
        });
    }
    eventSignatures = {
        SetEnableDepositRoute: "uint256,uint256,address,bool",
        SetPoolRebalanceRoute: "uint256,address,address",
        ProposeRootBundle: "uint32,uint8,uint256[],bytes32,bytes32,bytes32,address",
        RootBundleExecuted: "uint256,uint256,uint256,address[],uint256[],int256[],int256[],address",
    };
    setCrossChainContractsEvent(l2ChainId, adapter, spokePool, overrides = {}) {
        const event = "CrossChainContractsSet";
        const topics = [];
        const args = {
            l2ChainId,
            adapter,
            spokePool,
        };
        return this.eventManager.generateEvent({
            event,
            address: this.hubPool.address,
            topics: topics.map((topic) => topic.toString()),
            args,
            blockNumber: overrides.blockNumber,
        });
    }
    setPoolRebalanceRoute(destinationChainId, l1Token, destinationToken, overrides = {}) {
        const event = "SetPoolRebalanceRoute";
        const topics = [destinationChainId, l1Token, destinationToken];
        const args = {
            destinationChainId,
            l1Token,
            destinationToken,
        };
        return this.eventManager.generateEvent({
            event,
            address: this.hubPool.address,
            topics: topics.map((topic) => topic.toString()),
            args,
            blockNumber: overrides.blockNumber,
        });
    }
    proposeRootBundle(challengePeriodEndTimestamp, poolRebalanceLeafCount, bundleEvaluationBlockNumbers, poolRebalanceRoot, relayerRefundRoot, slowRelayRoot, proposer, overrides = {}) {
        const event = "ProposeRootBundle";
        poolRebalanceRoot ??= "XX";
        relayerRefundRoot ??= "XX";
        slowRelayRoot ??= "XX";
        proposer ??= (0, utils_1.randomAddress)();
        const topics = [poolRebalanceRoot, relayerRefundRoot, proposer];
        const args = {
            challengePeriodEndTimestamp,
            poolRebalanceLeafCount,
            bundleEvaluationBlockNumbers,
            poolRebalanceRoot,
            relayerRefundRoot,
            slowRelayRoot,
            proposer,
        };
        return this.eventManager.generateEvent({
            event,
            address: this.hubPool.address,
            topics: topics.map((topic) => topic.toString()),
            args,
            blockNumber: overrides.blockNumber,
        });
    }
    executeRootBundle(groupIndex, leafId, chainId, l1Tokens, bundleLpFees, netSendAmounts, runningBalances, caller, overrides = {}) {
        const event = "RootBundleExecuted";
        caller ??= (0, utils_1.randomAddress)();
        const topics = [leafId, chainId, caller];
        const args = {
            groupIndex,
            leafId,
            chainId,
            l1Tokens,
            bundleLpFees,
            netSendAmounts,
            runningBalances,
            caller,
        };
        return this.eventManager.generateEvent({
            event,
            address: this.hubPool.address,
            topics: topics.map((topic) => topic.toString()),
            args,
            blockNumber: overrides.blockNumber,
        });
    }
}
exports.MockHubPoolClient = MockHubPoolClient;
//# sourceMappingURL=MockHubPoolClient.js.map