//
// Created by HuangXin on 2023/5/8.
//
#include <zlog_module.h>
#include <sys/time.h>
#include <bits/types/struct_tm.h>
#include <time.h>
#include <string.h>
#include "main.h"

#define SIZE_1K (1024)

static const char *logLevelStr(int level) {
    switch (level) {
        case ZLOG_LEVEL_TRACE:
            return "T";
        case ZLOG_LEVEL_DEBUG:
            return "D";
        case ZLOG_LEVEL_INFO:
            return "I";
        case ZLOG_LEVEL_NOTICE:
            return "N";
        case ZLOG_LEVEL_WARN:
            return "W";
        case ZLOG_LEVEL_ERROR:
            return "E";
        case ZLOG_LEVEL_FATAL:
            return "F";
        default:
            return "U";
    }
}

static void writeLogMsg(int level, char *pMsg, int mode) {
    struct tm     *local_t;
    time_t         t;
    struct timeval tv;
    char          *pBuf = strdup(pMsg);

    gettimeofday(&tv, NULL);

    time(&t);

    local_t           = localtime(&t);
    local_t->tm_isdst = (int)(tv.tv_usec / 1000);

    snprintf(pMsg, SIZE_1K, "[%02d:%02d:%02d:%03d] [%s] %s", local_t->tm_hour, local_t->tm_min, local_t->tm_sec,
             local_t->tm_isdst, logLevelStr(level), pBuf);

    free(pBuf);
    write_log_msg(pMsg, mode);
}

void format_log_msg(int level, int mode, const char *pMsg, ...) {
    char *pBuf = (char *)malloc(SIZE_1K);

    if (pBuf) {
        __builtin_va_list arg_ptr;
        memset(pBuf, 0, SIZE_1K);
        va_start(arg_ptr, pMsg);
        __builtin_vsnprintf(pBuf, SIZE_1K, pMsg, arg_ptr);
        va_end(arg_ptr);

        writeLogMsg(level, pBuf, mode);
        if (mode == 0) {
            free(pBuf);
        }
    }
}