import { openLix } from "../../lix/open-lix.js";
/**
 * Create an in-memory storage.
 *
 * Great for testing or quick prototyping.
 */
export const createLspInMemoryEnvironment = () => {
    const store = new Map();
    /**
     * Map of open lixes.
     *
     * @example
     *   openLixes.set('id', lix);
     *   openLixes.delete('id');
     *   openLixes.has('id');
     */
    const openLixes = new Map();
    /**
     * Map of open connections.
     *
     * @example
     *   openConnections['lix-id'].add('connection-id');
     *   openConnections['lix-id'].delete('connection-id');
     *   openConnections['lix-id'].has('connection-id');
     *   openConnections['lix-id'].size;
     */
    const openConnections = new Map();
    return {
        async hasLix(args) {
            return store.has(args.id);
        },
        async getLix(args) {
            return store.get(args.id);
        },
        async setLix(args) {
            store.set(args.id, args.blob);
        },
        async openLix(args) {
            const connectionId = Math.random().toString(36).slice(2);
            let lix;
            // TODO no concurrency guarantees
            if (openLixes.has(args.id)) {
                lix = openLixes.get(args.id);
            }
            else {
                const blob = store.get(args.id);
                lix = await openLix({
                    blob,
                    // don't sync the server with itself
                    keyValues: [{ key: "lix_sync", value: "false" }],
                });
                lix.engine.sqlite.exec("PRAGMA foreign_keys = OFF;");
                openLixes.set(args.id, lix);
            }
            if (openConnections.has(args.id)) {
                openConnections.get(args.id).add(connectionId);
            }
            else {
                openConnections.set(args.id, new Set([connectionId]));
            }
            return { lix, id: args.id, connectionId };
        },
        async closeLix(args) {
            const connections = openConnections.get(args.id);
            if (!connections) {
                throw new Error(`No open connections for lix ${args.id}`);
            }
            connections.delete(args.connectionId);
            if (connections.size === 0) {
                // TODO no concurrency guarantees
                const lix = openLixes.get(args.id);
                // await fileQueueSettled({ lix: lix! });
                const blob = await lix.toBlob();
                await lix.close();
                openConnections.delete(args.id);
                openLixes.delete(args.id);
                store.set(args.id, blob);
            }
        },
    };
};
// For backward compatibility
export const createLsaInMemoryEnvironment = createLspInMemoryEnvironment;
//# sourceMappingURL=create-in-memory-environment.js.map