import { __awaiter } from "tslib";
const DEFAULT_KEY_PREFIX = 'genesis-ai-session';
/**
 * A {@link SessionPersistenceProvider} backed by a Web Storage area. Both
 * `window.sessionStorage` and `window.localStorage` implement the `Storage`
 * API, so one class serves both: point it at `sessionStorage` for
 * refresh-survival that clears on tab close (the showcase default, O6), or at
 * `localStorage` for durable local persistence.
 *
 * Opt-in: a host constructs it and passes it through `chatConfig`; the library
 * never instantiates it on its own.
 *
 * @public
 */
export class WebStorageSessionProvider {
    constructor(storage, options = {}) {
        var _a, _b;
        this.storage = storage;
        this.keyPrefix = (_a = options.keyPrefix) !== null && _a !== void 0 ? _a : DEFAULT_KEY_PREFIX;
        this.saveDebounceMs = (_b = options.saveDebounceMs) !== null && _b !== void 0 ? _b : 0;
    }
    storageKey(sessionKey) {
        return `${this.keyPrefix}:${sessionKey}`;
    }
    /** Preferences key, namespaced apart from the session key so `clear` leaves it. */
    preferencesKey(sessionKey) {
        return `${this.keyPrefix}:prefs:${sessionKey}`;
    }
    load(sessionKey) {
        return __awaiter(this, void 0, void 0, function* () {
            const raw = this.storage.getItem(this.storageKey(sessionKey));
            if (!raw)
                return null;
            try {
                return JSON.parse(raw);
            }
            catch (_a) {
                // A corrupt or partially-written entry is treated as absent rather than
                // throwing — a bad snapshot must never block the assistant from starting.
                return null;
            }
        });
    }
    save(sessionKey, snapshot) {
        return __awaiter(this, void 0, void 0, function* () {
            const serialized = JSON.stringify(snapshot);
            try {
                this.storage.setItem(this.storageKey(sessionKey), serialized);
            }
            catch (e) {
                if (isQuotaExceeded(e)) {
                    throw new Error(`WebStorageSessionProvider: storage quota exceeded saving session "${sessionKey}" ` +
                        `(${serialized.length} chars). Compact the conversation or use a server-backed provider.`);
                }
                throw e;
            }
        });
    }
    clear(sessionKey) {
        return __awaiter(this, void 0, void 0, function* () {
            this.storage.removeItem(this.storageKey(sessionKey));
        });
    }
    loadPreferences(sessionKey) {
        return __awaiter(this, void 0, void 0, function* () {
            const raw = this.storage.getItem(this.preferencesKey(sessionKey));
            if (raw === null)
                return undefined;
            try {
                return JSON.parse(raw);
            }
            catch (_a) {
                // A corrupt entry is treated as "no preferences" — never block startup.
                return undefined;
            }
        });
    }
    savePreferences(sessionKey, preferences) {
        return __awaiter(this, void 0, void 0, function* () {
            // Small blob — quota is a non-issue, so no QuotaExceeded guard.
            this.storage.setItem(this.preferencesKey(sessionKey), JSON.stringify(preferences));
        });
    }
}
/**
 * Web Storage signals an exceeded quota with different `name`s across browsers
 * (`QuotaExceededError` everywhere modern; `NS_ERROR_DOM_QUOTA_REACHED` on
 * older Firefox). The legacy numeric `code`s (22 / 1014) are intentionally not
 * checked — they add nothing for the browsers this app targets.
 */
function isQuotaExceeded(e) {
    return (typeof DOMException !== 'undefined' &&
        e instanceof DOMException &&
        (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED'));
}
