"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheStorage = exports.CacheModel = void 0;
const middleware_1 = require("../routes/middleware");
const base_1 = require("./base");
class CacheModel extends base_1.BaseModel {
    constructor(storage) {
        super('cache', storage);
        this.Times = {
            None: 0,
            Second: 1 * 1000,
            Minute: 60 * 1000,
            Hour: middleware_1.CacheTimes.Minute * 60 * 1000,
            Day: middleware_1.CacheTimes.Hour * 24 * 1000,
            Month: middleware_1.CacheTimes.Day * 30 * 1000,
            Year: middleware_1.CacheTimes.Day * 365 * 1000
        };
        this.allowedPaging = [];
    }
    async onConnect() {
        await this.collection.createIndex({ key: 1, wallet: 1 }, { background: true, unique: true });
    }
    async expire(key, wallet) {
        await this.collection.updateOne({ key, wallet }, { $set: { expireTime: 0 } });
    }
    async setGlobal(key, value, cacheTime) {
        await this.collection.updateOne({ key }, { $set: { value, created: Date.now(), expireTime: cacheTime } }, { upsert: true });
    }
    async setForWallet(wallet, key, value, cacheTime) {
        await this.collection.updateOne({ wallet, key }, { $set: { value, created: Date.now(), expireTime: cacheTime } }, { upsert: true });
    }
    async getGlobal(key) {
        const found = await this.collection.findOne({ key, wallet: undefined });
        if (!found) {
            return null;
        }
        if (found.created + found.expireTime >= Date.now()) {
            // cache hit
            return found.value;
        }
        else {
            // cache miss
            this.collection.remove({ _id: found._id });
            return null;
        }
    }
    async getForWallet(wallet, key) {
        const found = await this.collection.findOne({ wallet, key });
        if (!found) {
            return null;
        }
        if (found.created + found.expireTime >= Date.now()) {
            // cache hit
            return found.value;
        }
        else {
            // cache miss
            this.collection.remove({ _id: found._id });
            return null;
        }
    }
    async getGlobalOrRefresh(key, onMiss, cacheTime) {
        const data = await this.getGlobal(key);
        if (data !== null) {
            return data;
        }
        else {
            const fetched = await onMiss();
            await this.setGlobal(key, fetched, cacheTime);
            return fetched;
        }
    }
    async getForWalletOrRefresh(wallet, key, onMiss, cacheTime) {
        const data = await this.getForWallet(wallet, key);
        if (data !== null) {
            return data;
        }
        else {
            const fetched = await onMiss();
            await this.setForWallet(wallet, key, fetched, cacheTime);
            return fetched;
        }
    }
}
exports.CacheModel = CacheModel;
exports.CacheStorage = new CacheModel();
//# sourceMappingURL=cache.js.map