import { customAlphabet, nanoid } from 'nanoid';
const userCodeAlphabet = customAlphabet('ABCDEFGHJKLMNPQRSTUVWXYZ23456789', 8);
const EXPIRY_SECONDS = 600;
const deviceKey = (code) => `dg:device:${code}`;
const userKey = (code) => `dg:user:${code}`;
export class RedisStore {
    r;
    constructor(r) {
        this.r = r;
    }
    async create(sessionId) {
        const now = Math.floor(Date.now() / 1000);
        const rec = {
            device_code: nanoid(32),
            user_code: userCodeAlphabet(),
            session_id: sessionId,
            status: 'pending',
            created_at: now,
            expires_at: now + EXPIRY_SECONDS,
        };
        const value = JSON.stringify(rec);
        await this.r.set(deviceKey(rec.device_code), value, 'EX', EXPIRY_SECONDS);
        await this.r.set(userKey(rec.user_code), rec.device_code, 'EX', EXPIRY_SECONDS);
        return rec;
    }
    async approveByUserCode(userCode, userId) {
        const deviceCode = await this.r.get(userKey(userCode));
        if (!deviceCode)
            return null;
        const rec = await this.poll(deviceCode);
        if (!rec)
            return null;
        rec.status = 'approved';
        rec.user_id = userId;
        const ttl = Math.max(rec.expires_at - Math.floor(Date.now() / 1000), 1);
        await this.r.set(deviceKey(deviceCode), JSON.stringify(rec), 'EX', ttl);
        return rec;
    }
    async poll(deviceCode) {
        const raw = await this.r.get(deviceKey(deviceCode));
        if (!raw)
            return null;
        return JSON.parse(raw);
    }
}
export class MemoryStore {
    byDevice = new Map();
    byUser = new Map();
    async create(sessionId) {
        const now = Math.floor(Date.now() / 1000);
        const rec = {
            device_code: nanoid(32),
            user_code: userCodeAlphabet(),
            session_id: sessionId,
            status: 'pending',
            created_at: now,
            expires_at: now + EXPIRY_SECONDS,
        };
        this.byDevice.set(rec.device_code, rec);
        this.byUser.set(rec.user_code, rec.device_code);
        return rec;
    }
    async approveByUserCode(userCode, userId) {
        const deviceCode = this.byUser.get(userCode);
        if (!deviceCode)
            return null;
        const rec = this.byDevice.get(deviceCode);
        if (!rec)
            return null;
        rec.status = 'approved';
        rec.user_id = userId;
        return rec;
    }
    async poll(deviceCode) {
        return this.byDevice.get(deviceCode) ?? null;
    }
}
//# sourceMappingURL=store.js.map