import { getKeyValueStore } from "./storage/index.js";
import { getRedisPrefixedKey, isRedis, getGlobalRedisClient } from "./storage/index.js";
import { createMetaStore } from "./storage/kv-base.js";
// Added to only where redis is not in use
// Allows just for IDE based debugging
export const EXPIRING_KEYS = new Set();
export const MINUTE_MS = 60 * 1000;
export const HOUR_MS = MINUTE_MS * 60;
export const DAY_MS = 24 * HOUR_MS;
export const MONTH_MS = 31 * DAY_MS;
export const DEFAULT_EXPIRES_IN_MS = 7 * DAY_MS;
export function getExpiresAt(ms = DEFAULT_EXPIRES_IN_MS, defaultExpiresAt) {
    return defaultExpiresAt ?? new Date(Date.now() + ms).toISOString();
}
export function getExpiresInMilliseconds(expiresAt) {
    const expiresAtMs = new Date(expiresAt).getTime();
    // now should be smaller than when it expires
    // so we should minus the current time from it, then that's our ms left
    return expiresAtMs - Date.now();
}
export function getExpiringStore(name, options) {
    const store = getKeyValueStore(name, options);
    function getKey(key) {
        return getRedisPrefixedKey(name, key);
    }
    return {
        ...store,
        async set(key, value) {
            const { expiresAt } = value;
            await store.set(key, value);
            const redisKey = getKey(key);
            if (!expiresAt) {
                // Not yet expiring
                if (isRedis()) {
                    const client = await getGlobalRedisClient();
                    await client.persist(redisKey);
                }
                return;
            }
            const expiresInMs = getExpiresInMilliseconds(expiresAt);
            if (isExpired(expiresInMs)) {
                // Already expired
                console.warn(`Deleting already expired key ${key}`);
                return await store.delete(key);
            }
            /* c8 ignore start */
            if (!isRedis()) {
                EXPIRING_KEYS.add(`${name}|${key}`);
                return;
            }
            /* c8 ignore stop */
            const expiresInSeconds = Math.ceil(expiresInMs / 1000);
            const client = await getGlobalRedisClient();
            await client.expire(redisKey, expiresInSeconds);
        },
        async get(key) {
            const value = await store.get(key);
            if (!value)
                return value;
            if (isRedis())
                return value; // trust redis expiry
            const { expiresAt } = value;
            if (!expiresAt)
                return value;
            if (isExpired(getExpiresInMilliseconds(expiresAt))) {
                return undefined;
            }
            return value;
        },
        meta(key) {
            return createMetaStore(getExpiringStore, name, key, options);
        }
    };
    function isExpired(expiresInMs) {
        return expiresInMs <= 0;
    }
}
//# sourceMappingURL=expiring-kv.js.map