//
// Created by xajhuang on 2023/2/6.
//

#ifndef VCPE_ZLOG_MODULE_H
#define VCPE_ZLOG_MODULE_H
#ifdef __cplusplus
extern "C" {
#endif

#include <zlog.h>

enum {
    ZLOG_LEVEL_TRACE = 10,
};

typedef enum {
    trace  = ZLOG_LEVEL_TRACE,
    debug  = ZLOG_LEVEL_DEBUG,
    info   = ZLOG_LEVEL_INFO,
    notice = ZLOG_LEVEL_NOTICE,
    warn   = ZLOG_LEVEL_WARN,
    error  = ZLOG_LEVEL_ERROR,
    fatal  = ZLOG_LEVEL_FATAL
} ZLOG_LV;

#define DEF_ZLOG_MOD(ZLOG_MOD)                           \
    ZLOG_MOD(ZLOG_MOD_MAIN, ZLOG_LEVEL_INFO, "MAIN")     \
    ZLOG_MOD(ZLOG_MOD_TASK, ZLOG_LEVEL_INFO, "TASK")     \
    ZLOG_MOD(ZLOG_MOD_INIT, ZLOG_LEVEL_INFO, "INIT")     \
    ZLOG_MOD(ZLOG_MOD_MISC, ZLOG_LEVEL_INFO, "MISC")     \
    ZLOG_MOD(ZLOG_MOD_WATCH, ZLOG_LEVEL_INFO, "WATCH")   \
    ZLOG_MOD(ZLOG_MOD_CONFIG, ZLOG_LEVEL_INFO, "CONFIG") \
    ZLOG_MOD(ZLOG_MOD_DB, ZLOG_LEVEL_INFO, "DB")         \
    ZLOG_MOD(ZLOG_MOD_NET, ZLOG_LEVEL_INFO, "NET")       \
    ZLOG_MOD(ZLOG_MOD_CRYPTO, ZLOG_LEVEL_INFO, "CRYPTO") \
    ZLOG_MOD(ZLOG_MOD_MQ, ZLOG_LEVEL_INFO, "MQ")         \
    ZLOG_MOD(ZLOG_MOD_PROTO, ZLOG_LEVEL_INFO, "PROTO")   \
    ZLOG_MOD(ZLOG_MOD_HTTPD, ZLOG_LEVEL_INFO, "HTTPD")   \
    ZLOG_MOD(ZLOG_MOD_JSCHEM, ZLOG_LEVEL_INFO, "JSCHEM") \
    ZLOG_MOD(ZLOG_MOD_USER, ZLOG_LEVEL_INFO, "USER")     \
    ZLOG_MOD(ZLOG_MOD_PPPOE, ZLOG_LEVEL_INFO, "PPPOE")   \
    ZLOG_MOD(ZLOG_MOD_VXLAN, ZLOG_LEVEL_INFO, "VXLAN")   \
    ZLOG_MOD(ZLOG_MOD_LWIP, ZLOG_LEVEL_INFO, "LWIP")     \
    ZLOG_MOD(ZM_DHCP, ZLOG_LEVEL_INFO, "DHCP")           \
    ZLOG_MOD(ZM_DHCP_NET, ZLOG_LEVEL_INFO, "DHCP_N")     \
    ZLOG_MOD(ZM_DHCP_POOL, ZLOG_LEVEL_INFO, "DHCP_P")    \
    ZLOG_MOD(ZM_DHCP_USR, ZLOG_LEVEL_INFO, "DHCP_U")     \
    ZLOG_MOD(ZM_DHCP_LEASE, ZLOG_LEVEL_INFO, "DHCP_L")   \
    ZLOG_MOD(ZM_DHCP_DB, ZLOG_LEVEL_INFO, "DHCP_DB")     \
    ZLOG_MOD(ZLOG_MOD_OPENDHCPD, ZLOG_LEVEL_INFO, "ODHCPD")

#define GENERATE_ZLOG_MOD_ENUM(ENUM, lv, x) ENUM,

typedef enum {
    DEF_ZLOG_MOD(GENERATE_ZLOG_MOD_ENUM)
} ZLOG_MOD_NAME;

#define hzlog_trace(cat, buf, buf_len) \
    hzlog(cat, __FILE__, sizeof(__FILE__) - 1, __func__, sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_DEBUG, buf, buf_len)

#define zlog_trace(cat, format, ...)                                                                              \
    zlog(cat, __FILE__, sizeof(__FILE__) - 1, __func__, sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_TRACE, format, \
         ##__VA_ARGS__)

#define LOG_MSG(level, format, ...)  LOG_MOD(level, ZLOG_MOD_MAIN, format, ##__VA_ARGS__)
#define LOG_MSG_HEX(level, buf, len) LOG_MOD_HEX(level, ZLOG_MOD_MAIN, (buf), (len))

#define LOG_MOD(level, mod, format, ...)                                  \
    do {                                                                  \
        if (zlog_verify_level(level, mod)) {                              \
            if (zlog_vni_tag_get()) {                                     \
                zlog_put_mdc("vni", zlog_vni_tag_get());                  \
            }                                                             \
            zlog_##level(zlog_get_mod_cat((mod)), format, ##__VA_ARGS__); \
        }                                                                 \
    } while (0)

#define LOG_MOD_HEX(level, mod, buf, len)                         \
    do {                                                          \
        if (zlog_verify_level(level, mod)) {                      \
            if (zlog_vni_tag_get()) {                             \
                zlog_put_mdc("vni", zlog_vni_tag_get());          \
            }                                                     \
            hzlog_##level(zlog_get_mod_cat((mod)), (buf), (len)); \
            printf("\n");                                         \
        }                                                         \
    } while (0)

zlog_category_t *zlog_get_mod_cat(ZLOG_MOD_NAME logMod);

int zlog_verify_level(int level, ZLOG_MOD_NAME logMod);

const char *zlog_vni_tag_get();

#ifdef __cplusplus
}
#endif
#endif    //VCPE_ZLOG_MODULE_H