"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RateLimitStorage = exports.RateLimitModel = exports.RateLimitTimes = void 0;
const base_1 = require("./base");
var RateLimitTimes;
(function (RateLimitTimes) {
    RateLimitTimes[RateLimitTimes["None"] = 0] = "None";
    RateLimitTimes[RateLimitTimes["Second"] = 1000] = "Second";
    RateLimitTimes[RateLimitTimes["Minute"] = 60000] = "Minute";
    RateLimitTimes[RateLimitTimes["Hour"] = 3600000] = "Hour";
    RateLimitTimes[RateLimitTimes["Day"] = 86400000] = "Day";
    RateLimitTimes[RateLimitTimes["Month"] = 2592000000] = "Month";
    RateLimitTimes[RateLimitTimes["Year"] = 31536000000] = "Year";
})(RateLimitTimes || (exports.RateLimitTimes = RateLimitTimes = {}));
class RateLimitModel extends base_1.BaseModel {
    constructor(storage) {
        super('ratelimits', storage);
        this.allowedPaging = [];
    }
    onConnect() {
        this.collection.createIndex({ identifier: 1, time: 1, method: 1, count: 1 }, { background: true });
        this.collection.createIndex({ expireAt: 1 }, { expireAfterSeconds: 0, background: true });
    }
    incrementAndCheck(identifier, method) {
        return Promise.all([
            this.collection.findOneAndUpdate({ identifier, method, period: 'second', time: { $gte: new Date(Date.now() - RateLimitTimes.Second) } }, {
                $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 2 * RateLimitTimes.Second) },
                $inc: { count: 1 }
            }, { upsert: true, returnOriginal: false }),
            this.collection.findOneAndUpdate({ identifier, method, period: 'minute', time: { $gte: new Date(Date.now() - RateLimitTimes.Minute) } }, {
                $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 2 * RateLimitTimes.Minute) },
                $inc: { count: 1 }
            }, { upsert: true, returnOriginal: false }),
            this.collection.findOneAndUpdate({ identifier, method, period: 'hour', time: { $gte: new Date(Date.now() - RateLimitTimes.Hour) } }, {
                $setOnInsert: { time: new Date(), expireAt: new Date(Date.now() + 2 * RateLimitTimes.Hour) },
                $inc: { count: 1 }
            }, { upsert: true, returnOriginal: false })
        ]);
    }
}
exports.RateLimitModel = RateLimitModel;
exports.RateLimitStorage = new RateLimitModel();
//# sourceMappingURL=rateLimit.js.map