import { __extends } from "tslib";
import assert from "assert";
import { ethers } from "ethers";
import { getCurrentTime, isDefined, utf8ToHex, spreadEventWithBlockNumber, } from "../../utils";
import { AcrossConfigStoreClient, DEFAULT_CONFIG_STORE_VERSION, GLOBAL_CONFIG_STORE_KEYS, } from "../AcrossConfigStoreClient";
import { getEventManager } from "./MockEvents";
var MockConfigStoreClient = /** @class */ (function (_super) {
    __extends(MockConfigStoreClient, _super);
    function MockConfigStoreClient(logger, configStore, eventSearchConfig, configStoreVersion, chainId, mockUpdate, availableChainIdsOverride) {
        if (eventSearchConfig === void 0) { eventSearchConfig = { from: 0, maxLookBack: 0 }; }
        if (chainId === void 0) { chainId = 1; }
        if (mockUpdate === void 0) { mockUpdate = false; }
        var _this = _super.call(this, logger, configStore, eventSearchConfig, configStoreVersion) || this;
        _this.configStoreVersion = DEFAULT_CONFIG_STORE_VERSION;
        // Event signatures. Not strictly required, but they make generated events more recognisable.
        _this.eventSignatures = {
            OwnershipTransferred: "address,address",
            UpdatedGlobalConfig: "bytes32,string",
            UpdatedTokenConfig: "address,string",
        };
        _this.chainId = chainId;
        _this.eventManager = mockUpdate ? getEventManager(chainId, _this.eventSignatures) : null;
        if (isDefined(_this.eventManager) && _this.eventManager) {
            _this.updateGlobalConfig(GLOBAL_CONFIG_STORE_KEYS.CHAIN_ID_INDICES, JSON.stringify(availableChainIdsOverride), {
                blockNumber: _this.eventManager.blockNumber,
            });
        }
        return _this;
    }
    MockConfigStoreClient.prototype.setAvailableChains = function (chainIds) {
        this.availableChainIdsOverride = chainIds;
    };
    MockConfigStoreClient.prototype.getChainIdIndicesForBlock = function (block) {
        var _a;
        return (_a = this.availableChainIdsOverride) !== null && _a !== void 0 ? _a : _super.prototype.getChainIdIndicesForBlock.call(this, block);
    };
    MockConfigStoreClient.prototype.getConfigStoreVersionForBlock = function (_blockNumber) {
        return this.configStoreVersion === DEFAULT_CONFIG_STORE_VERSION
            ? _super.prototype.getConfigStoreVersionForBlock.call(this, _blockNumber)
            : this.configStoreVersion;
    };
    MockConfigStoreClient.prototype.setConfigStoreVersion = function (version) {
        this.configStoreVersion = version;
    };
    MockConfigStoreClient.prototype._update = function () {
        // Backwards compatibility for pre-existing MockConfigStoreClient users.
        if (this.eventManager === null) {
            return _super.prototype._update.call(this);
        }
        var eventNames = ["UpdatedGlobalConfig", "UpdatedTokenConfig"];
        var latestBlockSearched = this.eventManager.blockNumber;
        // Ensure an array for every requested event exists, in the requested order.
        // All requested event types must be populated in the array (even if empty).
        var globalConfigUpdateTimes = [];
        var _events = eventNames.map(function () { return []; });
        for (var _i = 0, _a = this.eventManager.getEvents().flat(); _i < _a.length; _i++) {
            var event_1 = _a[_i];
            var idx = eventNames.indexOf(event_1.event);
            if (idx !== -1) {
                _events[idx].push(event_1);
            }
            if (event_1.event === "UpdatedGlobalConfig") {
                globalConfigUpdateTimes.push(getCurrentTime());
            }
        }
        // Transform 2d-events array into a record.
        var events = Object.fromEntries(eventNames.map(function (eventName, idx) { return [eventName, _events[idx]]; }));
        return Promise.resolve({
            success: true,
            chainId: this.chainId,
            searchEndBlock: this.eventSearchConfig.to || latestBlockSearched,
            events: {
                updatedGlobalConfigEvents: events["UpdatedGlobalConfig"].map(spreadEventWithBlockNumber),
                globalConfigUpdateTimes: globalConfigUpdateTimes,
                updatedTokenConfigEvents: events["UpdatedTokenConfig"].map(spreadEventWithBlockNumber),
            },
        });
    };
    MockConfigStoreClient.prototype.updateGlobalConfig = function (key, value, overrides) {
        if (overrides === void 0) { overrides = {}; }
        return this.generateConfig("UpdatedGlobalConfig", utf8ToHex(key), value, overrides);
    };
    MockConfigStoreClient.prototype.updateTokenConfig = function (key, value, overrides) {
        if (overrides === void 0) { overrides = {}; }
        // Verify that the key is a valid address
        if (ethers.utils.isAddress(key) === false) {
            throw new Error("Invalid address: ".concat(key));
        }
        return this.generateConfig("UpdatedTokenConfig", key, value, overrides);
    };
    MockConfigStoreClient.prototype.generateConfig = function (event, key, value, overrides) {
        if (overrides === void 0) { overrides = {}; }
        assert(this.eventManager !== null);
        var topics = [key, value];
        var args = { key: key, value: value };
        return this.eventManager.generateEvent({
            event: event,
            address: this.configStore.address,
            topics: topics.map(function (topic) { return topic.toString(); }),
            args: args,
            blockNumber: overrides.blockNumber,
        });
    };
    return MockConfigStoreClient;
}(AcrossConfigStoreClient));
export { MockConfigStoreClient };
//# sourceMappingURL=MockConfigStoreClient.js.map