import { getAuthenticationRoles } from "../../authentication/index.js";
import { createHash } from "crypto";
import { DEFAULT_EXPIRES_IN_MS, getCacheStore, PAGE_EXPIRES_IN_MS, } from "./store.js";
import { getGlobalCount } from "../storage/index.js";
import { getOrigin } from "../../listen/config.js";
import { getExpiresAt } from "../expiring-kv.js";
import { commit, packageIdentifier } from "../../package.js";
function getSortedRoles() {
    return getAuthenticationRoles()
        .slice()
        .sort((a, b) => (a < b ? -1 : 1));
}
function getCacheKey(givenKey, roles = getSortedRoles()) {
    const hash = createHash("sha512");
    roles.forEach((role, index) => {
        hash.update(`role: ${role} ${index}`);
    });
    // Reset if we change the version of the module
    hash.update(packageIdentifier);
    // Reset if we deploy a new commit
    hash.update(commit);
    hash.update(givenKey);
    return hash.digest().toString("hex");
}
export async function addCachedPage(url, value) {
    const fullUrl = new URL(url, getOrigin()).toString();
    return addCached({
        key: fullUrl,
        value,
        expiresAt: getExpiresAt(PAGE_EXPIRES_IN_MS),
    });
}
export async function getCachedPage(url) {
    const fullUrl = new URL(url, getOrigin()).toString();
    return getCached(fullUrl);
}
export async function addExpiring(data) {
    return addCached({
        ...data,
        type: "expiring",
    });
}
export async function addCached(data) {
    const store = getCacheStore();
    const roles = data.role ? [] : getSortedRoles();
    const key = data.stable ?
        data.key :
        getCacheKey(data.key, roles);
    const counter = await getGlobalCount();
    const type = data.type || "counter";
    const cached = {
        ...data,
        role: data.role !== false,
        type,
        expiresAt: getExpiresAt(DEFAULT_EXPIRES_IN_MS, data.expiresAt),
        createdAt: new Date().toISOString(),
        roles,
        counter,
        counterType: "global",
    };
    // console.log({ key, cached });
    await store.set(key, cached);
}
export async function getCached(givenKey, stable) {
    const store = getCacheStore();
    const roles = getSortedRoles();
    const key = stable ? givenKey : getCacheKey(givenKey, roles);
    const countPromise = getGlobalCount();
    const value = await store.get(key);
    // console.log({ key, value })
    if (!value)
        return undefined;
    if (!value.type || value.type === "counter") {
        const counter = await countPromise;
        if (value.counter !== counter)
            return undefined;
    }
    if (value.role !== false) {
        if (value.roles.length !== roles.length)
            return undefined;
        const everyRoleSame = roles.every((role) => value.roles.includes(role));
        // Just one last check just to be absolutely sure
        if (!everyRoleSame) {
            console.warn("Cache key somehow isn't restricting users to a single role view of objects");
            console.warn("Users should only be able to access the cache for their exact role set");
            return undefined;
        }
    }
    return value.value;
}
export async function deleteCached(givenKey, stable) {
    const store = getCacheStore();
    const roles = getSortedRoles();
    const key = stable ? givenKey : getCacheKey(givenKey, roles);
    await store.delete(key);
}
//# sourceMappingURL=index.js.map