import { createDocumentStore } from "../state/state-backend.js";
export class SessionLockStore {
    store;
    constructor(workspace, backend = "json") {
        this.store = createDocumentStore({
            workspace,
            fileName: "locks.json",
            sqliteKey: "locks",
            backend,
        });
    }
    get(contextKey, now = Date.now()) {
        const lock = this.readPayload().locks[contextKey];
        if (!lock) {
            return null;
        }
        if (!lock.expiresAt || lock.expiresAt > now) {
            return lock;
        }
        this.store.update((current) => {
            const payload = normalizeLockPayload(current);
            const currentLock = payload.locks[contextKey];
            if (currentLock?.expiresAt && currentLock.expiresAt <= now) {
                delete payload.locks[contextKey];
            }
            return payload;
        });
        return null;
    }
    set(contextKey, owner, ttlMs) {
        const now = Date.now();
        const lock = {
            contextKey,
            ownerUserId: owner.userId,
            ownerLabel: owner.label,
            ownerChannel: owner.channel,
            ownerChannelUserId: owner.channelUserId,
            createdAt: now,
            expiresAt: ttlMs > 0 ? now + ttlMs : undefined,
        };
        this.store.update((current) => {
            const payload = normalizeLockPayload(current);
            payload.locks[contextKey] = lock;
            return payload;
        });
        return lock;
    }
    clear(contextKey) {
        let existed = false;
        this.store.update((current) => {
            const payload = normalizeLockPayload(current);
            existed = Boolean(payload.locks[contextKey]);
            delete payload.locks[contextKey];
            return payload;
        });
        return existed;
    }
    list() {
        const now = Date.now();
        const payload = this.store.update((current) => {
            const payload = normalizeLockPayload(current);
            payload.locks = Object.fromEntries(Object.values(payload.locks)
                .filter((lock) => !lock.expiresAt || lock.expiresAt > now)
                .map((lock) => [lock.contextKey, lock]));
            return payload;
        });
        const locks = Object.values(payload.locks).filter((lock) => !lock.expiresAt || lock.expiresAt > now);
        return locks.sort((left, right) => right.createdAt - left.createdAt);
    }
    readPayload() {
        return normalizeLockPayload(this.store.read());
    }
}
function normalizeLockPayload(payload) {
    if (!payload || payload.version !== 1 || !payload.locks || typeof payload.locks !== "object") {
        return { version: 1, locks: {} };
    }
    return {
        version: 1,
        locks: Object.fromEntries(Object.entries(payload.locks).filter(([, lock]) => isSessionLock(lock))),
    };
}
export function canWriteWithLock(lock, userId, isAdmin) {
    if (!lock) {
        return true;
    }
    return isAdmin || Boolean(userId && userId === lock.ownerUserId);
}
function isSessionLock(value) {
    if (!value || typeof value !== "object" || Array.isArray(value)) {
        return false;
    }
    const candidate = value;
    return typeof candidate.contextKey === "string" &&
        typeof candidate.ownerUserId === "string" &&
        typeof candidate.createdAt === "number" &&
        (candidate.expiresAt === undefined || typeof candidate.expiresAt === "number");
}
