"use strict";
/**
 * Production-grade structured logging system
 * Provides performance tracing and operational visibility
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.moduleResolverLogger = exports.moduleRegistryLogger = exports.moduleLoaderLogger = exports.moduleSystemLogger = exports.LoggerFactory = exports.Logger = exports.PerformanceTrace = void 0;
/**
 * Performance tracer for tracking operation latency
 */
class PerformanceTrace {
    constructor(operation, metadata = {}) {
        this.completed = false;
        this.operation = operation;
        this.metadata = metadata;
        this.startTime = Date.now();
    }
    /**
     * Complete the trace and log the duration
     */
    complete(logger, result, error) {
        if (this.completed) {
            return 0;
        }
        const duration = Date.now() - this.startTime;
        this.completed = true;
        const logData = {
            operation: this.operation,
            duration,
            result: result || 'success',
            ...this.metadata,
        };
        if (error) {
            logData.error = {
                name: error.name,
                message: error.message,
                stack: error.stack,
            };
            logger.warn(`Operation failed: ${this.operation}`, logData);
        }
        else {
            logger.debug(`Operation completed: ${this.operation}`, logData);
        }
        return duration;
    }
    /**
     * Get current duration without completing the trace
     */
    getCurrentDuration() {
        return Date.now() - this.startTime;
    }
}
exports.PerformanceTrace = PerformanceTrace;
/**
 * Production logger with structured output and tracing
 */
class Logger {
    constructor(component, config = {}) {
        this.component = component;
        this.config = {
            level: config.level || 'info',
            format: config.format || 'json',
            enableTracing: config.enableTracing ?? true,
            enableColors: config.enableColors ?? true,
            timestamp: config.timestamp ?? true,
            includeStack: config.includeStack ?? false,
        };
    }
    /**
     * Create a child logger with additional context
     */
    child(additionalComponent, metadata = {}) {
        const childLogger = new Logger(`${this.component}.${additionalComponent}`, this.config);
        // Store metadata for all child logger calls
        childLogger.defaultMetadata =
            metadata;
        return childLogger;
    }
    /**
     * Start a performance trace
     */
    startTrace(operation, metadata = {}) {
        if (!this.config.enableTracing) {
            return new PerformanceTrace(operation, metadata);
        }
        const traceId = this.generateTraceId();
        const spanId = this.generateSpanId();
        this.debug(`Starting operation: ${operation}`, {
            operation,
            traceId,
            spanId,
            ...metadata,
        });
        const trace = new PerformanceTrace(operation, { traceId, spanId, ...metadata });
        return trace;
    }
    /**
     * Measure and log the execution of an async operation
     */
    async measureAsync(operation, fn, metadata = {}) {
        const trace = this.startTrace(operation, metadata);
        try {
            const result = await fn();
            trace.complete(this, 'success');
            return result;
        }
        catch (error) {
            trace.complete(this, 'error', error);
            throw error;
        }
    }
    /**
     * Measure and log the execution of a sync operation
     */
    measureSync(operation, fn, metadata = {}) {
        const trace = this.startTrace(operation, metadata);
        try {
            const result = fn();
            trace.complete(this, 'success');
            return result;
        }
        catch (error) {
            trace.complete(this, 'error', error);
            throw error;
        }
    }
    trace(message, metadata) {
        this.log('trace', message, metadata);
    }
    debug(message, metadata) {
        this.log('debug', message, metadata);
    }
    info(message, metadata) {
        this.log('info', message, metadata);
    }
    warn(message, metadata) {
        this.log('warn', message, metadata);
    }
    error(message, error, metadata) {
        let errorData = {};
        let metaData = metadata || {};
        if (error instanceof Error) {
            errorData = {
                error: {
                    name: error.name,
                    message: error.message,
                    stack: this.config.includeStack ? error.stack : undefined,
                    code: error.code,
                },
            };
        }
        else if (error && typeof error === 'object') {
            metaData = { ...error, ...metaData };
        }
        this.log('error', message, { ...errorData, ...metaData });
    }
    fatal(message, error, metadata) {
        this.error(message, error, metadata);
        // In production, this might trigger alerts or shutdown procedures
    }
    log(level, message, metadata) {
        if (!this.shouldLog(level)) {
            return;
        }
        const entry = {
            timestamp: this.config.timestamp ? new Date().toISOString() : '',
            level,
            message,
            component: this.component,
            ...(this.defaultMetadata || {}),
            ...metadata,
        };
        const output = this.formatLogEntry(entry);
        // Write to appropriate stream
        const stream = level === 'error' || level === 'fatal' ? process.stderr : process.stdout;
        stream.write(output + '\n');
    }
    shouldLog(level) {
        return Logger.LOG_LEVELS[level] >= Logger.LOG_LEVELS[this.config.level];
    }
    formatLogEntry(entry) {
        if (this.config.format === 'json') {
            return JSON.stringify(entry);
        }
        // Pretty format for development
        const color = this.config.enableColors ? Logger.COLORS[entry.level] : '';
        const reset = this.config.enableColors ? Logger.RESET_COLOR : '';
        const timestamp = entry.timestamp ? `[${entry.timestamp}] ` : '';
        const level = entry.level.toUpperCase().padEnd(5);
        const component = entry.component ? `[${entry.component}] ` : '';
        let message = `${color}${timestamp}${level}${reset} ${component}${entry.message}`;
        // Add operation and duration if available
        if (entry.operation) {
            message += ` (${entry.operation}`;
            if (entry.duration !== undefined) {
                message += ` - ${entry.duration}ms`;
            }
            message += ')';
        }
        // Add metadata if present
        const metadataEntries = Object.entries(entry).filter(([key]) => !['timestamp', 'level', 'message', 'component', 'operation', 'duration'].includes(key));
        if (metadataEntries.length > 0) {
            const metadata = Object.fromEntries(metadataEntries);
            message += ` ${JSON.stringify(metadata)}`;
        }
        return message;
    }
    generateTraceId() {
        return (Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15));
    }
    generateSpanId() {
        return Math.random().toString(36).substring(2, 10);
    }
    /**
     * Update logger configuration
     */
    updateConfig(config) {
        Object.assign(this.config, config);
    }
    /**
     * Get current configuration
     */
    getConfig() {
        return { ...this.config };
    }
}
exports.Logger = Logger;
Logger.LOG_LEVELS = {
    trace: 0,
    debug: 1,
    info: 2,
    warn: 3,
    error: 4,
    fatal: 5,
};
Logger.COLORS = {
    trace: '\x1b[90m', // gray
    debug: '\x1b[36m', // cyan
    info: '\x1b[32m', // green
    warn: '\x1b[33m', // yellow
    error: '\x1b[31m', // red
    fatal: '\x1b[35m', // magenta
};
Logger.RESET_COLOR = '\x1b[0m';
/**
 * Global logger factory and manager
 */
class LoggerFactory {
    /**
     * Get or create a logger for a component
     */
    static getLogger(component) {
        if (!this.loggers.has(component)) {
            this.loggers.set(component, new Logger(component, this.globalConfig));
        }
        return this.loggers.get(component);
    }
    /**
     * Update global configuration for all loggers
     */
    static updateGlobalConfig(config) {
        Object.assign(this.globalConfig, config);
        // Update existing loggers
        for (const logger of this.loggers.values()) {
            logger.updateConfig(config);
        }
    }
    /**
     * Set log level for all loggers
     */
    static setLevel(level) {
        this.updateGlobalConfig({ level });
    }
    /**
     * Enable or disable tracing for all loggers
     */
    static setTracing(enabled) {
        this.updateGlobalConfig({ enableTracing: enabled });
    }
    /**
     * Set output format for all loggers
     */
    static setFormat(format) {
        this.updateGlobalConfig({ format });
    }
    /**
     * Get all registered loggers
     */
    static getAllLoggers() {
        return new Map(this.loggers);
    }
    /**
     * Clear all loggers
     */
    static clearAll() {
        this.loggers.clear();
    }
}
exports.LoggerFactory = LoggerFactory;
LoggerFactory.loggers = new Map();
LoggerFactory.globalConfig = {
    level: 'info',
    format: 'json',
    enableTracing: true,
    enableColors: false,
    timestamp: true,
    includeStack: false,
};
// Export default logger for module system
exports.moduleSystemLogger = LoggerFactory.getLogger('module-system');
exports.moduleLoaderLogger = LoggerFactory.getLogger('module-loader');
exports.moduleRegistryLogger = LoggerFactory.getLogger('module-registry');
exports.moduleResolverLogger = LoggerFactory.getLogger('module-resolver');
//# sourceMappingURL=logger.js.map