"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PENDING_FETCH_REQUESTS = void 0;
exports.resetCrlCacheCleaner = resetCrlCacheCleaner;
exports.getCrl = getCrl;
const asn1_js_rfc5280_1 = __importDefault(require("asn1.js-rfc5280"));
const axios_1 = __importDefault(require("axios"));
const logger_1 = __importDefault(require("../../logger"));
const global_config_typed_1 = __importDefault(require("../../global_config_typed"));
const crl_cache_1 = require("./crl_cache");
exports.PENDING_FETCH_REQUESTS = new Map();
let memoryCacheCleanerInterval;
let diskCacheCleanerInterval;
let crlCacheCleanerCreated = false;
function resetCrlCacheCleaner() {
    clearInterval(memoryCacheCleanerInterval);
    clearInterval(diskCacheCleanerInterval);
    crlCacheCleanerCreated = false;
}
async function getCrl(url, options) {
    const logDebug = (msg) => (0, logger_1.default)().debug(`getCrl[${url}]: ${msg}`);
    if (!crlCacheCleanerCreated) {
        crlCacheCleanerCreated = true;
        const oneHour = 1000 * 60 * 60;
        logDebug('Starting periodic memory cache cleaner');
        memoryCacheCleanerInterval = setInterval(crl_cache_1.clearExpiredCrlFromMemoryCache, oneHour).unref();
        logDebug('Starting periodic disk cache cleaner');
        (0, crl_cache_1.clearExpiredCrlFromDiskCache)();
        diskCacheCleanerInterval = setInterval(crl_cache_1.clearExpiredCrlFromDiskCache, oneHour).unref();
    }
    const pendingFetchRequest = exports.PENDING_FETCH_REQUESTS.get(url);
    if (pendingFetchRequest) {
        logDebug(`Returning pending fetch request`);
        return pendingFetchRequest;
    }
    if (options.inMemoryCache) {
        logDebug(`Checking in-memory cache`);
        const cachedCrl = (0, crl_cache_1.getCrlFromMemory)(url);
        if (cachedCrl) {
            logDebug(`Returning from in-memory cache`);
            return cachedCrl;
        }
    }
    if (options.onDiskCache) {
        logDebug(`Checking on-disk cache`);
        const cachedCrl = await (0, crl_cache_1.getCrlFromDisk)(url);
        if (cachedCrl) {
            if (options.inMemoryCache) {
                (0, crl_cache_1.setCrlInMemory)(url, cachedCrl);
            }
            logDebug(`Returning from disk cache`);
            return cachedCrl;
        }
    }
    const fetchPromise = (async () => {
        try {
            logDebug(`Downloading CRL`);
            const { data } = await axios_1.default.get(url, {
                timeout: global_config_typed_1.default.getValue('crlDownloadTimeout'),
                responseType: 'arraybuffer',
                maxContentLength: global_config_typed_1.default.getValue('crlDownloadMaxSize'),
            });
            logDebug(`Parsing CRL`);
            const parsedCrl = asn1_js_rfc5280_1.default.CertificateList.decode(data, 'der');
            if (options.inMemoryCache) {
                logDebug('Saving to memory cache');
                (0, crl_cache_1.setCrlInMemory)(url, parsedCrl);
            }
            if (options.onDiskCache) {
                logDebug('Saving to disk cache');
                await (0, crl_cache_1.writeCrlToDisk)(url, data);
            }
            return parsedCrl;
        }
        finally {
            exports.PENDING_FETCH_REQUESTS.delete(url);
        }
    })();
    exports.PENDING_FETCH_REQUESTS.set(url, fetchPromise);
    return fetchPromise;
}
//# sourceMappingURL=crl_fetcher.js.map