import * as plugins from '../plugins.js';
import { logger } from '../logger.js';
import { defaultTsmDbPath } from '../paths.js';
/**
 * DcRouterDb - Unified database layer for DCRouter
 *
 * Replaces both StorageManager (flat-file key-value) and CacheDb (embedded MongoDB).
 * All data is stored as smartdata document classes in a single database.
 *
 * Two modes:
 * - **Embedded** (default): Spawns a LocalSmartDb (Rust-based MongoDB-compatible engine)
 * - **External**: Connects to a provided MongoDB URL
 */
export class DcRouterDb {
    static instance = null;
    localSmartDb = null;
    smartdataDb;
    options;
    isStarted = false;
    constructor(options = {}) {
        this.options = {
            mongoDbUrl: options.mongoDbUrl || '',
            storagePath: options.storagePath || defaultTsmDbPath,
            dbName: options.dbName || 'dcrouter',
            debug: options.debug || false,
        };
    }
    /**
     * Get or create the singleton instance
     */
    static getInstance(options) {
        if (!DcRouterDb.instance) {
            DcRouterDb.instance = new DcRouterDb(options);
        }
        return DcRouterDb.instance;
    }
    /**
     * Reset the singleton instance (useful for testing)
     */
    static resetInstance() {
        DcRouterDb.instance = null;
    }
    /**
     * Start the database
     * - If mongoDbUrl is provided, connects directly to external MongoDB
     * - Otherwise, starts an embedded LocalSmartDb instance
     */
    async start() {
        if (this.isStarted) {
            logger.log('warn', 'DcRouterDb already started');
            return;
        }
        try {
            let connectionUri;
            if (this.options.mongoDbUrl) {
                // External MongoDB mode
                connectionUri = this.options.mongoDbUrl;
                logger.log('info', `DcRouterDb connecting to external MongoDB`);
            }
            else {
                // Embedded LocalSmartDb mode
                await plugins.fsUtils.ensureDir(this.options.storagePath);
                this.localSmartDb = new plugins.smartdb.LocalSmartDb({
                    folderPath: this.options.storagePath,
                });
                const connectionInfo = await this.localSmartDb.start();
                connectionUri = connectionInfo.connectionUri;
                if (this.options.debug) {
                    logger.log('debug', `LocalSmartDb started with URI: ${connectionUri}`);
                }
                logger.log('info', `DcRouterDb started embedded instance at ${this.options.storagePath}`);
            }
            // Initialize smartdata ORM
            this.smartdataDb = new plugins.smartdata.SmartdataDb({
                mongoDbUrl: connectionUri,
                mongoDbName: this.options.dbName,
            });
            await this.smartdataDb.init();
            this.isStarted = true;
            logger.log('info', `DcRouterDb ready (db: ${this.options.dbName})`);
        }
        catch (error) {
            logger.log('error', `Failed to start DcRouterDb: ${error.message}`);
            throw error;
        }
    }
    /**
     * Stop the database
     */
    async stop() {
        if (!this.isStarted) {
            return;
        }
        try {
            // Close smartdata connection
            if (this.smartdataDb) {
                await this.smartdataDb.close();
            }
            // Stop embedded LocalSmartDb if running
            if (this.localSmartDb) {
                await this.localSmartDb.stop();
                this.localSmartDb = null;
            }
            this.isStarted = false;
            logger.log('info', 'DcRouterDb stopped');
        }
        catch (error) {
            logger.log('error', `Error stopping DcRouterDb: ${error.message}`);
            throw error;
        }
    }
    /**
     * Get the smartdata database instance for @Collection decorators
     */
    getDb() {
        if (!this.isStarted) {
            throw new Error('DcRouterDb not started. Call start() first.');
        }
        return this.smartdataDb;
    }
    /**
     * Check if the database is ready
     */
    isReady() {
        return this.isStarted;
    }
    /**
     * Whether running in embedded mode (LocalSmartDb) vs external MongoDB
     */
    isEmbedded() {
        return !this.options.mongoDbUrl;
    }
    /**
     * Get the storage path (only relevant for embedded mode)
     */
    getStoragePath() {
        return this.options.storagePath;
    }
    /**
     * Get the database name
     */
    getDbName() {
        return this.options.dbName;
    }
}
//# sourceMappingURL=data:application/json;base64, 