import assert from "assert";
import { utils as ethersUtils } from "ethers";
import { random } from "lodash";
import { isDefined } from "../../utils";
const { id, keccak256, toUtf8Bytes } = ethersUtils;
export class EventManager {
    blockNumber;
    logIndexes = {};
    events = [];
    minBlockRange = 10;
    eventSignatures = {};
    constructor(blockNumber = 0) {
        this.blockNumber = blockNumber;
    }
    addEventSignatures(eventSignatures) {
        Object.entries(eventSignatures).forEach(([event, signature]) => {
            if (isDefined(this.eventSignatures[event])) {
                assert(signature === this.eventSignatures[event], `Event ${event} conflict detected.`);
            }
            this.eventSignatures[event] = signature;
        });
    }
    addEvent(event) {
        this.events.push(event);
    }
    getEvents() {
        const events = this.events;
        this.events = [];
        return events;
    }
    // Reset internal state. Useful when a long-lived EventManager instance is
    // reused across test contexts that begin at different block numbers.
    reset(blockNumber = 0) {
        this.blockNumber = blockNumber;
        this.logIndexes = {};
        this.events = [];
    }
    generateEvent(inputs) {
        const { address, event, topics, data, args } = inputs;
        let { blockNumber, transactionIndex } = inputs;
        const eventSignature = `${event}(${this.eventSignatures[event]})`;
        // Increment the block number by at least 1, by default. The caller may override
        // to force the same block number to be used, but never a previous block number.
        blockNumber ??= random(this.blockNumber + 1, this.blockNumber + this.minBlockRange, false);
        assert(blockNumber >= this.blockNumber, `${blockNumber} < ${this.blockNumber}`);
        this.blockNumber = blockNumber;
        transactionIndex ??= random(1, 32, false);
        const _logIndex = `${blockNumber}-${transactionIndex}`;
        this.logIndexes[_logIndex] ??= 0;
        const generatedEvent = {
            event,
            blockNumber,
            transactionIndex,
            logIndex: this.logIndexes[_logIndex]++,
            transactionHash: id(`Across-${event}-${blockNumber}-${transactionIndex}-${random(1, 100_000)}`),
            removed: false,
            address,
            data: data ?? id(`Across-random-txndata-${random(1, 100_000)}`),
            topics: [keccak256(toUtf8Bytes(eventSignature)), ...topics],
            args,
            blockHash: id(`Across-blockHash-${random(1, 100_000)}`),
        };
        this.addEvent(generatedEvent);
        return generatedEvent;
    }
}
//# sourceMappingURL=MockEvents.js.map