#ifndef __LOGGER_H__
#define __LOGGER_H__

#include <spdlog/spdlog.h>

// #define LOG_TRACE(...)    spdlog::default_logger()->trace(__VA_ARGS__)
// #define LOG_DEBUG(...)    spdlog::default_logger()->debug(__VA_ARGS__)
// #define LOG_INFO(...)     spdlog::default_logger()->info(__VA_ARGS__)
// #define LOG_WARN(...)     spdlog::default_logger()->warn(__VA_ARGS__)
// #define LOG_ERROR(...)    spdlog::default_logger()->error(__VA_ARGS__)
// #define LOG_CRITICAL(...) spdlog::default_logger()->critical(__VA_ARGS__)

#define LOG_TRACE(...)      SPDLOG_LOGGER_CALL(spdlog::default_logger().get(), spdlog::level::trace, __VA_ARGS__)
#define LOG_DEBUG(...)      SPDLOG_LOGGER_CALL(spdlog::default_logger().get(), spdlog::level::debug, __VA_ARGS__)
#define LOG_INFO(...)       SPDLOG_LOGGER_CALL(spdlog::default_logger().get(), spdlog::level::info, __VA_ARGS__)
#define LOG_ERROR(...)      SPDLOG_LOGGER_CALL(spdlog::default_logger().get(), spdlog::level::err, __VA_ARGS__)
#define LOG_WARN(...)       SPDLOG_LOGGER_CALL(spdlog::default_logger().get(), spdlog::level::warn, __VA_ARGS__)
#define LOG_CRITICAL(...)   SPDLOG_LOGGER_CALL(spdlog::default_logger().get(), spdlog::level::critical, __VA_ARGS__)


class Logger
{
public:
    enum LOG_LEVEL : int {
        TRACE = SPDLOG_LEVEL_TRACE,
        DEBUG = SPDLOG_LEVEL_DEBUG,
        INFO = SPDLOG_LEVEL_INFO,
        WARN = SPDLOG_LEVEL_WARN,
        ERR = SPDLOG_LEVEL_ERROR,
        CRITICAL = SPDLOG_LEVEL_CRITICAL,
        OFF = SPDLOG_LEVEL_OFF,
        N_LEVELS
    };

    Logger();
    ~Logger();

    static void setup(LOG_LEVEL level);
};

#endif // LOGGER_H