"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupAll = exports.module = exports.setupLogger = exports.customTransports = exports.customFormat = exports.sanitizedConfig = exports.disableColors = exports.defaultLogFile = void 0;
const winston_daily_rotate_file_1 = __importDefault(require("@zwave-js/winston-daily-rotate-file"));
const fs_extra_1 = require("fs-extra");
const winston_1 = __importDefault(require("winston"));
const app_1 = require("../config/app");
const utils_1 = require("./utils");
const path = __importStar(require("path"));
const { format, transports, addColors } = winston_1.default;
const { combine, timestamp, label, printf, colorize, splat } = format;
exports.defaultLogFile = 'z-ui_%DATE%.log';
exports.disableColors = process.env.NO_LOG_COLORS === 'true';
// ensure store and logs directories exist
(0, fs_extra_1.ensureDirSync)(app_1.storeDir);
(0, fs_extra_1.ensureDirSync)(app_1.logsDir);
// custom colors for timestamp and module
addColors({
    time: 'grey',
    module: 'bold',
});
const colorizer = colorize();
/**
 * Generate logger configuration starting from settings.gateway
 */
function sanitizedConfig(module, config) {
    config = config || {};
    const filePath = (0, utils_1.joinPath)(app_1.logsDir, config.logFileName || exports.defaultLogFile);
    return {
        module: module || '-',
        enabled: config.logEnabled !== undefined ? config.logEnabled : true,
        level: config.logLevel || 'info',
        logToFile: config.logToFile !== undefined ? config.logToFile : false,
        filePath: filePath,
    };
}
exports.sanitizedConfig = sanitizedConfig;
/**
 * Return a custom logger format
 */
function customFormat(config, noColor = false) {
    noColor = noColor || exports.disableColors;
    const formats = [
        splat(), // used for formats like: logger.log('info', Message %s', strinVal)
        timestamp({ format: 'YYYY-MM-DD HH:mm:ss.SSS' }),
        format((info) => {
            info.level = info.level.toUpperCase();
            return info;
        })(),
        label({ label: config.module.toUpperCase() }),
    ];
    if (!noColor) {
        formats.push(colorize({ level: true }));
    }
    // must be added at last
    formats.push(printf((info) => {
        if (!noColor) {
            info.timestamp = colorizer.colorize('time', info.timestamp);
            info.label = colorizer.colorize('module', info.label || '-');
        }
        return `${info.timestamp} ${info.level} ${info.label}: ${info.message}${info.stack ? '\n' + info.stack : ''}`;
    }));
    return combine(...formats);
}
exports.customFormat = customFormat;
/**
 * Create the base transports based on settings provided
 */
function customTransports(config) {
    const transportsList = [];
    if (process.env.ZUI_NO_CONSOLE !== 'true') {
        transportsList.push(new transports.Console({
            format: customFormat(config),
            level: config.level,
            stderrLevels: ['error'],
        }));
    }
    if (config.logToFile) {
        let fileTransport;
        if (process.env.DISABLE_LOG_ROTATION === 'true') {
            fileTransport = new transports.File({
                format: customFormat(config, true),
                filename: config.filePath,
                level: config.level,
            });
        }
        else {
            fileTransport = new winston_daily_rotate_file_1.default({
                filename: config.filePath,
                auditFile: (0, utils_1.joinPath)(app_1.logsDir, 'zui-logs.audit.json'),
                datePattern: 'YYYY-MM-DD',
                createSymlink: true,
                symlinkName: path
                    .basename(config.filePath)
                    .replace(`_%DATE%`, '_current'),
                zippedArchive: true,
                maxFiles: process.env.ZUI_LOG_MAXFILES || '7d',
                maxSize: process.env.ZUI_LOG_MAXSIZE || '50m',
                level: config.level,
                format: customFormat(config, true),
            });
        }
        transportsList.push(fileTransport);
    }
    return transportsList;
}
exports.customTransports = customTransports;
/**
 * Setup a logger
 */
function setupLogger(container, module, config) {
    const sanitized = sanitizedConfig(module, config);
    // Winston automatically reuses an existing module logger
    const logger = container.add(module);
    logger.configure({
        format: combine(format.errors({ stack: true }), format.json()), // to correctly parse errors
        silent: !sanitized.enabled,
        level: sanitized.level,
        transports: customTransports(sanitized),
    });
    logger.module = module;
    logger.setup = (cfg) => setupLogger(container, module, cfg);
    return logger;
}
exports.setupLogger = setupLogger;
const logContainer = new winston_1.default.Container();
/**
 * Create a new logger for a specific module
 */
function module(module) {
    return setupLogger(logContainer, module);
}
exports.module = module;
/**
 * Setup all loggers starting from config
 */
function setupAll(config) {
    logContainer.loggers.forEach((logger) => {
        logger.setup(config);
    });
}
exports.setupAll = setupAll;
exports.default = logContainer.loggers;
