#ifndef LOG4_H
#define LOG4_H

#if defined(__cplusplus) && __cplusplus >= 201103L
  #define LOG_TLS_SPEC thread_local
#else
  /* C 或旧编译器，走 GCC 扩展 */
  #define LOG_TLS_SPEC __thread
#endif

/* ★统一的对外声明（别在其他头/源里再声明不同版本！） */
extern LOG_TLS_SPEC int g_log_code_tls;

#ifdef __cplusplus

#include <string>
#include <map>

//防止#include <log4cplus/logger.h>里的冲突
#ifdef min
#undef min
#endif

#ifdef max
#undef max
#endif
//防止#include <log4cplus/logger.h>里的冲突

#include "logger.h"
#include <set>
#include "loggingmacros.h"

#include "appender.h"

#define LOGTYPE_COM 1
#define LOGTYPE_DATA 2

struct TypedLogger {
    log4cplus::Logger logger;
    int logtype;
    TypedLogger();
    TypedLogger(const log4cplus::Logger& l, int t);
};

struct DebugSwitch {
    bool debug_open;
    std::set<std::string> targets;
    int min_level;
    std::map<int, bool> type_enable;

    DebugSwitch();
    void open();
    void close();
    void set_target(const std::string& name);
    void set_level(int level);
    void enable_type(int type);
    void disable_type(int type);
    bool match(const std::string& logger_name, int level, int logtype);
};

extern std::map<std::string, TypedLogger> logger_map;
extern DebugSwitch g_debug_switch;

extern void send_reply_to_queue(const std::string& guid, const std::string& step, const std::string& result);


//std::string get_front_type_from_subdir();


// 不带 Appender 的版本
log4cplus::Logger init_logger(const std::string& full_name,
                              const std::string& file_dir,
                              const std::string& base_file);

// 带 Appender 的版本
log4cplus::Logger init_logger(const std::string& full_name,
                              const std::string& file_dir,
                              const std::string& base_file,
                              log4cplus::SharedAppenderPtr fileAppender);

void process_log_command(const std::string& id, const std::string& level, const std::string& grade, const std::string& logtype_str);


void update_log_entries_countdown();

extern "C" {
#endif
void remove_loggers_by_terminal_id(const std::string& terminal_id_cstr);
void init_logger_process();
void init_loggers();
void init_loggers_bydevid(const std::string& dev_id);

void log_debug(const char* key, const char* msg);
void log_info(const char* key, const char* msg);
void log_warn(const char* key, const char* msg);
void log_error(const char* key, const char* msg);

void send_reply_to_queue_c(const char* guid, const char* step, const char* result);
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);

// ====================== ★新增：线程局部变量透传 code ======================
// 说明：使用编译器的 TLS（__thread）保存当前日志的 code 值。
//      在每次打日志前写入，打完后恢复，Appender 读取该值写入 JSON。


// ====================== ★新增结束 ======================


// ====================== 日志宏区域 ======================
// 原始不带 code 的实现（兼容/复用）
#define DIY_LOG(LEVEL_FUNC, KEY, ...)                             \
    do {                                                          \
        char buf[256];                                            \
        format_log_msg(buf, sizeof(buf), __VA_ARGS__);            \
        LEVEL_FUNC(KEY, buf);                                     \
    } while (0)

// ★新增：带 code 的实现（C/C++ 通用，使用 TLS 保存/恢复）
#define DIY_LOG_CODE(LEVEL_FUNC, KEY, CODE_INT, ...)              \
    do {                                                          \
        int __old_code__ = g_log_code_tls;                        /* 备份旧值 */ \
        g_log_code_tls = (int)(CODE_INT);                         /* 设置本次日志 code */ \
        char buf[256];                                            \
        format_log_msg(buf, sizeof(buf), __VA_ARGS__);            \
        LEVEL_FUNC(KEY, buf);                                     /* 输出日志 */ \
        g_log_code_tls = __old_code__;                            /* 恢复旧值 */ \
    } while (0)

// ★修改：默认宏改为 code=0（兼容原有用法）
#define DIY_ERRORLOG(KEY, ...) DIY_LOG_CODE(log_error, KEY, 0, __VA_ARGS__)   // ★修改：默认 code=0
#define DIY_WARNLOG(KEY,  ...) DIY_LOG_CODE(log_warn,  KEY, 0, __VA_ARGS__)   // ★修改：默认 code=0
#define DIY_INFOLOG(KEY,  ...) DIY_LOG_CODE(log_info,  KEY, 0, __VA_ARGS__)   // ★修改：默认 code=0
#define DIY_DEBUGLOG(KEY, ...) DIY_LOG_CODE(log_debug, KEY, 0, __VA_ARGS__)   // ★修改：默认 code=0

// ★新增：显式传入 code 的便捷宏
// 用法示例：DIY_WARNLOG_CODE(full_key_m_c, warn_recallstart, "【WARN】监测点:%s ...", ...);
#define DIY_ERRORLOG_CODE(KEY, CODE_INT, ...) DIY_LOG_CODE(log_error, KEY, CODE_INT, __VA_ARGS__)  // ★新增
#define DIY_WARNLOG_CODE(KEY,  CODE_INT, ...) DIY_LOG_CODE(log_warn,  KEY, CODE_INT, __VA_ARGS__)  // ★新增
#define DIY_INFOLOG_CODE(KEY,  CODE_INT, ...) DIY_LOG_CODE(log_info,  KEY, CODE_INT, __VA_ARGS__)  // ★新增
#define DIY_DEBUGLOG_CODE(KEY, CODE_INT, ...) DIY_LOG_CODE(log_debug, KEY, CODE_INT, __VA_ARGS__)  // ★新增


// ====================== 日志宏区域 ======================


typedef enum LogCode {
    LOG_CODE_OTHER             = 99,   /* 其他类型 */
    LOG_CODE_LEDGER            = 100,  /* 台账类型 */
    LOG_CODE_RPTINIT           = 101,  /* 报告初始化 */
    LOG_CODE_ICD_AND_DOWNLOAD  = 200,  /* ICD 和文件下载类型 */
    LOG_CODE_TRANSIENT         = 300,  /* 暂态发生 */
    LOG_CODE_TRANSIENT_COMM    = 301,  /* 暂态接口 */
    LOG_CODE_COMTRADE_FILE     = 302,  /* 录波文件（Comtrade） */
    LOG_CODE_MQ                = 400,  /* MQ发送 */
    LOG_CODE_RT_DATA           = 401,  /* 实时数据 */
    LOG_CODE_LEDGER_UPDATE     = 402,  /* 台账更新 */
    LOG_CODE_PROCESS_CONTROL   = 403,  /* 进程控制 */
    LOG_CODE_RECALL            = 404,  /* 补招相关 */
    LOG_CODE_LOG_REQUEST       = 405,  /* 日志请求 */
    LOG_CODE_REPORT            = 500,  /* 报告处理 */
    LOG_CODE_COMM              = 600,  /* 通讯状态 */
    LOG_CODE_SPACE_ALARM       = 700   /* 空间告警 */
} LogCode;


#ifdef __cplusplus
}
#endif



#endif // LOG4_H
