/**
 * MongoDB Cache Driver
 * Uses MongoDB Atlas Data API (HTTPS) for zero-dependency integration
 */
import { Env } from '../../config/env.js';
import { Logger } from '../../config/logger.js';
import { ErrorFactory } from '../../exceptions/ZintrustError.js';
/**
 * MongoDB Cache Driver
 * Uses MongoDB Atlas Data API (HTTPS) for zero-dependency integration
 * Sealed namespace for immutability
 */
export const MongoDriver = Object.freeze({
    /**
     * Create a new MongoDB driver instance
     */
    create() {
        const uri = Env.MONGO_URI;
        const db = Env.MONGO_DB;
        const collection = 'cache';
        const request = async (action, body) => {
            if (uri === '') {
                Logger.warn('MONGO_URI not configured. MongoDB Cache request ignored.');
                return null;
            }
            try {
                const response = await fetch(`${uri}/action/${action}`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Access-Control-Request-Headers': '*',
                    },
                    body: JSON.stringify({
                        dataSource: 'Cluster0',
                        database: db,
                        collection: collection,
                        ...body,
                    }),
                });
                return await response.json();
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                ErrorFactory.createTryCatchError(`MongoDB Cache Error: ${message}`);
                return null;
            }
        };
        return {
            async get(key) {
                const result = (await request('findOne', { filter: { _id: key } }));
                if (result?.document === undefined || result.document === null)
                    return null;
                const doc = result.document;
                if (doc.expires !== null && doc.expires < Date.now()) {
                    await this.delete(key);
                    return null;
                }
                return doc.value;
            },
            async set(key, value, ttl) {
                const expires = ttl === undefined ? null : Date.now() + ttl * 1000;
                await request('updateOne', {
                    filter: { _id: key },
                    update: { $set: { value, expires } },
                    upsert: true,
                });
            },
            async delete(key) {
                await request('deleteOne', { filter: { _id: key } });
            },
            async clear() {
                await request('deleteMany', { filter: {} });
            },
            async has(key) {
                const result = (await request('findOne', { filter: { _id: key } }));
                return result?.document !== undefined && result.document !== null;
            },
        };
    },
});
