"use strict";
/**
 * Centralized error handler for CCS CLI
 *
 * Provides unified error handling with:
 * - Consistent error formatting
 * - Exit code management
 * - Cleanup callback execution
 * - Debug mode support
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.assertOrExit = exports.withErrorHandling = exports.exitWithSuccess = exports.exitWithError = exports.handleError = void 0;
const exit_codes_1 = require("./exit-codes");
const error_types_1 = require("./error-types");
const cleanup_registry_1 = require("./cleanup-registry");
const logging_1 = require("../services/logging");
const logger = (0, logging_1.createLogger)('cli:error-handler');
/**
 * Debug mode flag - set via CCS_DEBUG environment variable
 */
const isDebugMode = () => {
    return process.env['CCS_DEBUG'] === '1' || process.env['CCS_DEBUG'] === 'true';
};
/**
 * Format error message for display
 * Uses ASCII-only formatting per codebase standards (no emojis)
 */
function formatErrorMessage(error) {
    if ((0, error_types_1.isCCSError)(error)) {
        return `[X] ${error.message}`;
    }
    if (error instanceof Error) {
        return `[X] ${error.message}`;
    }
    if (typeof error === 'string') {
        return `[X] ${error}`;
    }
    return '[X] An unexpected error occurred';
}
/**
 * Get exit code from error
 * CCSError types have their own codes, others default to GENERAL_ERROR
 */
function getExitCode(error) {
    if ((0, error_types_1.isCCSError)(error)) {
        return error.code;
    }
    return exit_codes_1.ExitCode.GENERAL_ERROR;
}
/**
 * Log debug information for an error
 * Only outputs when CCS_DEBUG is enabled
 */
function logDebugInfo(error, code) {
    if (!isDebugMode())
        return;
    console.error('');
    console.error('[i] Debug information:');
    console.error(`    Exit code: ${code} (${exit_codes_1.EXIT_CODE_DESCRIPTIONS[code] || 'Unknown'})`);
    if (error instanceof Error) {
        console.error(`    Error type: ${error.constructor.name}`);
        if (error.stack) {
            console.error('    Stack trace:');
            const stackLines = error.stack.split('\n').slice(1, 6);
            for (const line of stackLines) {
                console.error(`      ${line.trim()}`);
            }
        }
    }
    // Log additional properties for CCSError types
    if ((0, error_types_1.isCCSError)(error)) {
        console.error(`    Recoverable: ${error.recoverable}`);
    }
}
/**
 * Central error handler
 * Formats error, runs cleanup, and exits with appropriate code
 *
 * @param error - The error to handle
 * @returns never - Always exits the process
 */
function handleError(error) {
    // Run cleanup callbacks first
    (0, cleanup_registry_1.runCleanup)();
    const code = getExitCode(error);
    const message = formatErrorMessage(error);
    logger.error('command.unhandled_error', 'Unhandled CLI error', {
        exitCode: code,
        error,
    });
    // Output error message to stderr
    console.error(message);
    // Log debug info if enabled
    logDebugInfo(error, code);
    // Exit with appropriate code
    process.exit(code);
}
exports.handleError = handleError;
/**
 * Exit with an error message and code
 * Convenience function for simple error exits
 *
 * @param message - Error message to display
 * @param code - Exit code (defaults to GENERAL_ERROR)
 * @returns never - Always exits the process
 */
function exitWithError(message, code = exit_codes_1.ExitCode.GENERAL_ERROR) {
    (0, cleanup_registry_1.runCleanup)();
    logger.error('command.exit_error', 'CLI exited with error', {
        exitCode: code,
        message,
    });
    console.error(`[X] ${message}`);
    if (isDebugMode()) {
        console.error('');
        console.error(`[i] Exit code: ${code} (${exit_codes_1.EXIT_CODE_DESCRIPTIONS[code] || 'Unknown'})`);
    }
    process.exit(code);
}
exports.exitWithError = exitWithError;
/**
 * Exit with success
 * Runs cleanup and exits with SUCCESS code
 *
 * @param message - Optional success message to display
 * @returns never - Always exits the process
 */
function exitWithSuccess(message) {
    (0, cleanup_registry_1.runCleanup)();
    logger.info('command.exit_success', 'CLI exited successfully', {
        message: message || null,
    });
    if (message) {
        console.log(`[OK] ${message}`);
    }
    process.exit(exit_codes_1.ExitCode.SUCCESS);
}
exports.exitWithSuccess = exitWithSuccess;
/**
 * Create a wrapped error handler for async operations
 * Wraps an async function to catch and handle errors
 */
function withErrorHandling(fn) {
    return async (...args) => {
        try {
            await fn(...args);
        }
        catch (error) {
            handleError(error);
        }
    };
}
exports.withErrorHandling = withErrorHandling;
/**
 * Assert a condition, throwing a CCSError if false
 */
function assertOrExit(condition, message, code = exit_codes_1.ExitCode.GENERAL_ERROR) {
    if (!condition) {
        exitWithError(message, code);
    }
}
exports.assertOrExit = assertOrExit;
//# sourceMappingURL=error-handler.js.map