/**
 * Composite Logger
 *
 * Combines multiple loggers to write to all of them simultaneously.
 * Used to send logs to both the console (respecting user log level)
 * and the internal trace logger (always at trace level for debugging).
 */
import { format } from 'node:util';
import { ErrorCode, getExitCode } from './errors';
function isErrorCode(value) {
    return typeof value === 'string' && Object.values(ErrorCode).includes(value);
}
/**
 * A logger that delegates to multiple child loggers
 */
export class CompositeLogger {
    loggers;
    constructor(loggers) {
        this.loggers = loggers;
    }
    trace(message, ...args) {
        for (const logger of this.loggers) {
            logger.trace(message, ...args);
        }
    }
    debug(message, ...args) {
        for (const logger of this.loggers) {
            logger.debug(message, ...args);
        }
    }
    info(message, ...args) {
        for (const logger of this.loggers) {
            logger.info(message, ...args);
        }
    }
    warn(message, ...args) {
        for (const logger of this.loggers) {
            logger.warn(message, ...args);
        }
    }
    error(message, ...args) {
        for (const logger of this.loggers) {
            logger.error(message, ...args);
        }
    }
    fatal(message, ...args) {
        const maybeErrorCode = args[args.length - 1];
        if (isErrorCode(maybeErrorCode)) {
            const formatArgs = args.slice(0, -1);
            const formattedMessage = format(message, ...formatArgs);
            for (const logger of this.loggers) {
                try {
                    logger.error(formattedMessage);
                }
                catch {
                    // Keep fatal exits reliable even if one delegate cannot write.
                }
            }
            process.exit(getExitCode(maybeErrorCode));
        }
        // Call fatal on all loggers, but only the first one will exit
        for (const logger of this.loggers) {
            try {
                logger.fatal(message, ...args);
            }
            catch {
                // Ignore - the logger will exit the process
            }
        }
        // Fallback exit if none of the loggers exit
        process.exit(1);
    }
    child(opts) {
        // Create child loggers for all delegates
        const childLoggers = this.loggers.map((logger) => logger.child(opts));
        return new CompositeLogger(childLoggers);
    }
    /**
     * Add a logger to the composite
     */
    addLogger(logger) {
        this.loggers.push(logger);
    }
    /**
     * Get all loggers in the composite
     */
    getLoggers() {
        return [...this.loggers];
    }
}
/**
 * Create a composite logger from multiple loggers
 */
export function createCompositeLogger(...loggers) {
    return new CompositeLogger(loggers);
}
//# sourceMappingURL=composite-logger.js.map