"use strict";
/**
 * Cleanup registry for CCS CLI
 *
 * Manages cleanup callbacks that should be run on exit or error.
 * Used to clean up resources like:
 * - Spawned processes (proxies, child processes)
 * - Temporary files
 * - Network connections
 * - Open file handles
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCleanupScope = exports.hasCleanupRun = exports.getCleanupCount = exports.clearCleanup = exports.runCleanup = exports.registerCleanup = void 0;
/**
 * Registry of cleanup callbacks
 * Executed in LIFO order (last registered = first executed)
 */
const cleanupCallbacks = [];
/**
 * Flag to prevent double execution
 */
let cleanupRan = false;
/**
 * Register a cleanup callback
 * Callbacks are executed in LIFO order (stack-like behavior)
 *
 * @param fn - Cleanup function to register
 * @returns Unregister function to remove the callback
 */
function registerCleanup(fn) {
    cleanupCallbacks.push(fn);
    // Return unregister function
    return () => {
        const index = cleanupCallbacks.indexOf(fn);
        if (index !== -1) {
            cleanupCallbacks.splice(index, 1);
        }
    };
}
exports.registerCleanup = registerCleanup;
/**
 * Run all registered cleanup callbacks
 * Executes in LIFO order, catches and logs individual errors
 * Can only be run once per process
 */
function runCleanup() {
    if (cleanupRan) {
        return;
    }
    cleanupRan = true;
    const isDebug = process.env['CCS_DEBUG'] === '1' || process.env['CCS_DEBUG'] === 'true';
    // Execute in reverse order (LIFO)
    while (cleanupCallbacks.length > 0) {
        const callback = cleanupCallbacks.pop();
        if (callback) {
            try {
                callback();
            }
            catch (error) {
                // Log cleanup errors in debug mode but don't throw
                if (isDebug) {
                    const message = error instanceof Error ? error.message : String(error);
                    console.error(`[!] Cleanup error: ${message}`);
                }
            }
        }
    }
}
exports.runCleanup = runCleanup;
/**
 * Clear all registered cleanup callbacks
 * Primarily used for testing
 */
function clearCleanup() {
    cleanupCallbacks.length = 0;
    cleanupRan = false;
}
exports.clearCleanup = clearCleanup;
/**
 * Get the number of registered cleanup callbacks
 * Primarily used for testing
 */
function getCleanupCount() {
    return cleanupCallbacks.length;
}
exports.getCleanupCount = getCleanupCount;
/**
 * Check if cleanup has already run
 * Primarily used for testing
 */
function hasCleanupRun() {
    return cleanupRan;
}
exports.hasCleanupRun = hasCleanupRun;
/**
 * Create a cleanup scope for automatic resource management
 * Resources registered within the scope are cleaned up when done
 *
 * @example
 * ```typescript
 * const scope = createCleanupScope();
 * scope.register(() => process.kill());
 * try {
 *   // ... do work
 * } finally {
 *   scope.cleanup();
 * }
 * ```
 */
function createCleanupScope() {
    const scopeCallbacks = [];
    const unregisters = [];
    return {
        register: (fn) => {
            scopeCallbacks.push(fn);
            // Also register with global cleanup in case of unexpected exit
            const unregister = registerCleanup(fn);
            unregisters.push(unregister);
        },
        cleanup: () => {
            // Unregister from global cleanup first
            for (const unregister of unregisters) {
                unregister();
            }
            // Execute scope callbacks in LIFO order
            while (scopeCallbacks.length > 0) {
                const callback = scopeCallbacks.pop();
                if (callback) {
                    try {
                        callback();
                    }
                    catch (_error) {
                        // Silently ignore scope cleanup errors
                    }
                }
            }
        },
    };
}
exports.createCleanupScope = createCleanupScope;
//# sourceMappingURL=cleanup-registry.js.map