/**
 * Return block number for `chain` in `bundleEvaluationBlockNumbers` using the mapping
 * in `chainIdListForBundleEvaluationBlockNumbers` to figure out which index in `bundleEvaluationBlockNumbers`
 * the block for `chain` is
 * @param bundleEvaluationBlockNumbers Usually, the bundle end blocks proposed in a root bundle.
 * @param chain The chain to look up block for
 * @param chainIdListForBundleEvaluationBlockNumbers The hardcoded sequence of chain IDs. For example:
 * [1, 10, 137, 288, 42161] implies that if we're looking for the block for chain 137, it's at index 2 in
 * `bundleEvaluationBlockNumbers`.
 * @returns The block for `chain` in `bundleEvaluationBlockNumbers`.
 */
export function getBlockForChain(bundleEvaluationBlockNumbers, chain, chainIdListForBundleEvaluationBlockNumbers) {
    var indexForChain = chainIdListForBundleEvaluationBlockNumbers.indexOf(chain);
    if (indexForChain === -1) {
        throw new Error("Could not find chain ".concat(chain, " in chain ID list ").concat(chainIdListForBundleEvaluationBlockNumbers));
    }
    var blockForChain = bundleEvaluationBlockNumbers[indexForChain];
    if (blockForChain === undefined) {
        throw new Error("Invalid block range for chain ".concat(chain));
    }
    return blockForChain;
}
/**
 * Similar concept as `getBlockForChain`, but returns the block range for `chain` in `blockRanges`.
 * @param blockRanges
 * @param chain
 * @param chainIdListForBundleEvaluationBlockNumbers
 * @returns
 */
export function getBlockRangeForChain(blockRanges, chain, chainIdListForBundleEvaluationBlockNumbers) {
    var indexForChain = chainIdListForBundleEvaluationBlockNumbers.indexOf(chain);
    if (indexForChain === -1) {
        throw new Error("Could not find chain ".concat(chain, " in chain ID list ").concat(chainIdListForBundleEvaluationBlockNumbers));
    }
    var blockRangeForChain = blockRanges[indexForChain];
    if (!blockRangeForChain || blockRangeForChain.length !== 2) {
        throw new Error("Invalid block range for chain ".concat(chain));
    }
    return blockRangeForChain;
}
/**
 * Return bundle block range for `rootBundle` whose bundle end blocks were included in the proposal.
 * This amounts to reconstructing the bundle range start block.
 * @param rootBundle Root bundle to return bundle block range for
 * @returns blockRanges: number[][], [[startBlock, endBlock], [startBlock, endBlock], ...]
 */
export function getImpliedBundleBlockRanges(hubPoolClient, configStoreClient, rootBundle) {
    var _a;
    var prevRootBundle = hubPoolClient.getLatestFullyExecutedRootBundle(rootBundle.blockNumber);
    // If chain is disabled for this bundle block range, end block should be same as previous bundle.
    // Otherwise the range should be previous bundle's endBlock + 1 to current bundle's end block.
    // Get enabled chains at the mainnet start block of the current root bundle.
    // We'll check each chain represented in the bundleEvaluationBlockNumbers to see if it's enabled and
    // use that to determine the implied block range.
    var mainnetStartBlock = (_a = prevRootBundle === null || prevRootBundle === void 0 ? void 0 : prevRootBundle.bundleEvaluationBlockNumbers[0].toNumber()) !== null && _a !== void 0 ? _a : 0;
    var enabledChainsAtMainnetStartBlock = configStoreClient.getEnabledChains(mainnetStartBlock);
    // Load all chain indices in order to map bundle evaluation block numbers to enabled chains list.
    var chainIdIndices = configStoreClient.getChainIdIndicesForBlock(rootBundle.blockNumber);
    var result = rootBundle.bundleEvaluationBlockNumbers.map(function (_endBlock, i) {
        var _a, _b, _c;
        var endBlock = _endBlock.toNumber();
        var bundleEndBlock = (_c = (_b = (_a = prevRootBundle === null || prevRootBundle === void 0 ? void 0 : prevRootBundle.bundleEvaluationBlockNumbers) === null || _a === void 0 ? void 0 : _a[i]) === null || _b === void 0 ? void 0 : _b.toNumber()) !== null && _c !== void 0 ? _c : 0;
        var fromBlock = bundleEndBlock === endBlock ? endBlock : bundleEndBlock + 1;
        var chainId = chainIdIndices[i];
        if (!enabledChainsAtMainnetStartBlock.includes(chainId)) {
            return [endBlock, endBlock];
        }
        return [fromBlock, endBlock];
    });
    // Lastly, sanity check the results to catch errors early:
    // 1. If the chain is enabled, the start block should be strictly less than to the end block.
    // 2. If the chain is disabled, the start block should be equal to the end block.
    result.forEach(function (_a, i) {
        var start = _a[0], end = _a[1];
        var chainId = chainIdIndices[i];
        if (enabledChainsAtMainnetStartBlock.includes(chainId)) {
            if (start > end) {
                throw new Error("Invalid block range for enabled chain ".concat(chainId, ": start block ").concat(start, " is greater than end block ").concat(end));
            }
        }
        else {
            if (start !== end) {
                throw new Error("Invalid block range for disabled chain ".concat(chainId, ": start block ").concat(start, " is not equal to end block ").concat(end));
            }
        }
    });
    return result;
}
//# sourceMappingURL=BundleUtils.js.map