import { __awaiter, __generator } from "tslib";
import { isDefined } from "./TypeGuards";
import { getCurrentTime } from "./TimeUtils";
import { shouldCache } from "./CachingUtils";
import { DEFAULT_CACHING_SAFE_LAG } from "../constants";
/**
 * @notice Get the block number for a given timestamp fresh from on-chain data if not found in redis cache.
 * If redis cache is not available, then requests block from blockFinder.
 * @param chainId Chain to load block finder for.
 * @param timestamp Approximate timestamp of the to requested block number.
 * @param blockFinder Caller can optionally pass in a block finder object to use instead of creating a new one
 * or loading from cache. This is useful for testing primarily.
 * @returns Block number for the requested timestamp.
 */
export function getCachedBlockForTimestamp(chainId, timestamp, blockFinder, cache, hints) {
    return __awaiter(this, void 0, void 0, function () {
        var resolver, key, result, blockNumber;
        var _this = this;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    resolver = function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
                        switch (_a.label) {
                            case 0: return [4 /*yield*/, blockFinder.getBlockForTimestamp(timestamp, hints || {})];
                            case 1: return [2 /*return*/, (_a.sent()).number];
                        }
                    }); }); };
                    // If no redis client, then request block from blockFinder.
                    if (!isDefined(cache)) {
                        return [2 /*return*/, resolver()];
                    }
                    key = "".concat(chainId, "_block_number_").concat(timestamp);
                    if (!shouldCache(timestamp, getCurrentTime(), DEFAULT_CACHING_SAFE_LAG)) return [3 /*break*/, 6];
                    return [4 /*yield*/, cache.get(key)];
                case 1:
                    result = _a.sent();
                    if (!(result !== null)) return [3 /*break*/, 2];
                    return [2 /*return*/, parseInt(result)];
                case 2: return [4 /*yield*/, resolver()];
                case 3:
                    blockNumber = _a.sent();
                    // Expire key after 90 days.
                    return [4 /*yield*/, cache.set(key, blockNumber.toString(), 60 * 60 * 24 * 90)];
                case 4:
                    // Expire key after 90 days.
                    _a.sent(); // 90 days
                    return [2 /*return*/, blockNumber];
                case 5: return [3 /*break*/, 7];
                case 6: return [2 /*return*/, resolver()];
                case 7: return [2 /*return*/];
            }
        });
    });
}
//# sourceMappingURL=BlockUtils.js.map