// SPDX-License-Identifier: Apache-2.0
/* eslint-disable @typescript-eslint/no-explicit-any */
import { createLogger, transports, format } from "winston";
import safeStringify from "fast-safe-stringify";
import BaseError from "../../../core/error/BaseError";
const { Console } = transports;
const { printf } = format;
export var LogLevel;
(function (LogLevel) {
    LogLevel["TRACE"] = "TRACE";
    LogLevel["INFO"] = "INFO";
    LogLevel["ERROR"] = "ERROR";
})(LogLevel || (LogLevel = {}));
export const LoggerOptionLevels = {
    [LogLevel.TRACE]: 3,
    [LogLevel.INFO]: 2,
    [LogLevel.ERROR]: 0,
};
export default class LogService {
    static instance = new LogService();
    static defaultFormat = printf(({ level, message, timestamp, other }) => {
        const formatOther = (val) => {
            return val
                .map((e) => {
                switch (typeof e) {
                    case "object":
                        return safeStringify(e);
                    default:
                        return e;
                }
            })
                .join("\t");
        };
        return `${timestamp} - [${level}]\t${message}\t${formatOther(other)}`;
    });
    logger;
    coreConfig = {
        levels: LoggerOptionLevels,
        exitOnError: false,
    };
    defaultConfig = {
        transports: new Console(),
        level: LogLevel.ERROR,
        format: LogService.defaultFormat,
    };
    constructor(opts) {
        LogService.instance = this;
        this.logger = createLogger({
            ...(opts ? { ...this.defaultConfig, ...opts } : this.defaultConfig),
            ...this.coreConfig,
        });
    }
    static log(level, message, params) {
        this.instance.logger.log(level, message, {
            timestamp: new Date().toISOString(),
            other: params,
        });
    }
    static logError(error, ...params) {
        if (error instanceof BaseError) {
            this.log(LogLevel.ERROR, error
                .toString(), params);
        }
        else {
            this.log(LogLevel.ERROR, error, params);
        }
    }
    static logInfo(message, ...params) {
        this.log(LogLevel.INFO, message, params);
    }
    static logTrace(message, ...params) {
        this.log(LogLevel.TRACE, message, params);
    }
}
