/*
 * @Author: yushuoqi yushuoqi@kylinos.cn
 * @Date: 2024-04-03 11:12:35
 * @LastEditors: yushuoqi yushuoqi@kylinos.cn
 * @LastEditTime: 2024-04-18 11:25:39
 * @FilePath: /kaiming/common/KMLogger.h
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/* KMLogger.h
 *
 * Copyright (C) 2023 OpenKylin, Inc
 */

#ifndef __KMLOGGER_H__
#define __KMLOGGER_H__

#include <stdarg.h>
#include <spdlog/spdlog.h>

#include <iostream>
#include <memory>

#include "KMSingleton.h"

#define STACK_SIZE 1024 * 8 * 10 * 100

#define F2S()                              \
    char *tmp = new char[STACK_SIZE];      \
    std::unique_ptr<char[]> data_ptr(tmp); \
    memset(tmp, 0x00, STACK_SIZE);         \
    va_list arg_list;                      \
    va_start(arg_list, fmt);               \
    vsprintf(tmp, fmt, arg_list);          \
    va_end(arg_list);                      \
    std::string log_msg = tmp;

class KMLogger : public KMSingleton<KMLogger>
{
public:
    KMLogger(token);
    ~KMLogger();

    void setLogLevel(spdlog::level::level_enum level);
    void setLogLevel(const std::string &level);

    void inline trace(const char *fmt, ...)
    {
        F2S();
        m_logger->trace(log_msg);
        m_logger->flush();
    }

    void inline debug(const char *fmt, ...)
    {
        F2S();
        m_logger->debug(log_msg);
        m_logger->flush();
    }

    void inline info(const char *fmt, ...)
    {
        F2S();
        m_logger->info(log_msg);
        m_logger->flush();
    }

    void inline warn(const char *fmt, ...)
    {
        F2S();
        m_logger->warn(log_msg);
        m_logger->flush();
    }

    void inline error(const char *fmt, ...)
    {
        F2S();
        m_logger->error(log_msg);
        m_logger->flush();
    }

    void inline critical(const char *fmt, ...)
    {
        F2S();
        m_logger->critical(log_msg);
        m_logger->flush();
    }

    void inline pinfo(const char *fmt, ...)
    {
        F2S();
        std::cout << log_msg << std::endl;
        m_logger->info(log_msg);
        m_logger->flush();
    }

    void inline perror(const char *fmt, ...)
    {
        F2S();
        std::cout << "\033[1;31m" << log_msg << "\033[0m" << std::endl;
        m_logger->error(log_msg);
        m_logger->flush();
    }

    void traceLog(const std::string &msg);
    void debugLog(const std::string &msg);
    void infoLog(const std::string &msg);
    void warnLog(const std::string &msg);
    void errorLog(const std::string &msg);
    void criticalLog(const std::string &msg);

private:
    std::string format2String(const char *fmt, ...);

private:
    std::shared_ptr<spdlog::logger> m_logger;
    spdlog::level::level_enum m_logLevel;
};

#define kmlogger KMLogger::instance()

#define COLOR_RED "\033[1;31m"
#define COLOR_YELLOW "\033[1;33m"
#define COLOR_RESET "\033[0m"

#define KMTrace(msg) KMLogger::instance().traceLog(msg)
#define KMDebug(msg) KMLogger::instance().debugLog(msg)
#define KMInfo(msg) KMLogger::instance().infoLog(msg)
#define KMWarn(msg) KMLogger::instance().warnLog(msg)
#define KMError(msg) KMLogger::instance().errorLog(msg)
#define KMCritical(msg) KMLogger::instance().criticalLog(msg)

#endif // !__KMLOGGER_H__
