import { __awaiter, __generator } from "tslib";
import assert from "assert";
import { BigNumber, delay as sleep } from "../../utils";
export { delay as sleep } from "../../utils";
// check if a value is not null or undefined, useful for numbers which could be 0.
// "is" syntax: https://stackoverflow.com/questions/40081332/what-does-the-is-keyword-do-in-typescript
/* eslint-disable-next-line @typescript-eslint/ban-types */
export function exists(value) {
    return value !== null && value !== undefined;
}
export function Balances(balances) {
    if (balances === void 0) { balances = {}; }
    function create(id, amount) {
        if (amount === void 0) { amount = "0"; }
        assert(!has(id), "balance already exists");
        return set(id, amount);
    }
    function has(id) {
        return exists(balances[id]);
    }
    function set(id, amount) {
        balances[id] = amount;
        return amount;
    }
    function add(id, amount) {
        return set(id, BigNumber.from(amount).add(getOrCreate(id)).toString());
    }
    function sub(id, amount) {
        return set(id, BigNumber.from(getOrCreate(id)).sub(amount).toString());
    }
    function get(id) {
        assert(has(id), "balance does not exist");
        return balances[id];
    }
    function getOrCreate(id) {
        if (has(id))
            return get(id);
        return create(id);
    }
    return { create: create, add: add, sub: sub, get: get, balances: balances, set: set, has: has, getOrCreate: getOrCreate };
}
// Loop forever but wait until execution is finished before starting next timer. Throw an error to break this
// or add another utlity function if you need it to end on condition.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function loop(fn, delay) {
    var args = [];
    for (var _i = 2; _i < arguments.length; _i++) {
        args[_i - 2] = arguments[_i];
    }
    return __awaiter(this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, fn.apply(void 0, args)];
                case 1:
                    _a.sent();
                    return [4 /*yield*/, sleep(delay)];
                case 2:
                    _a.sent();
                    _a.label = 3;
                case 3:
                    if (true) return [3 /*break*/, 0];
                    _a.label = 4;
                case 4: return [2 /*return*/];
            }
        });
    });
}
//# sourceMappingURL=utils.js.map