// rtt_log.c

#include "log.h"

#include "SEGGER_RTT.h"
#include "stdio.h"
#include <stdarg.h>

#if !defined(SEGGER_RTT_H)
#error                                                                         \
    "SEGGER_RTT.h not included. Please include SEGGER RTT library in your project."
#endif

#ifndef RTT_CTRL_TEXT_BLACK
#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m"
#define RTT_CTRL_TEXT_RED "\x1B[2;31m"
#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m"
#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m"
#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m"
#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m"
#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m"
#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m"
#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m"
#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m"
#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m"
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m"
#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m"
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m"
#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m"
#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m"
#define RTT_CTRL_BG_BLACK "\x1B[24;40m"
#define RTT_CTRL_BG_RED "\x1B[24;41m"
#define RTT_CTRL_BG_GREEN "\x1B[24;42m"
#define RTT_CTRL_BG_YELLOW "\x1B[24;43m"
#define RTT_CTRL_BG_BLUE "\x1B[24;44m"
#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m"
#define RTT_CTRL_BG_CYAN "\x1B[24;46m"
#define RTT_CTRL_BG_WHITE "\x1B[24;47m"
#define RTT_CTRL_RESET "\x1B[0m"
#endif

static const char *level_prefixes[] = {"[DEBUG] ", "[INFO]  ", "[WARN]  ",
                                       "[ERROR] "};

static const char *level_colors[] = {
    RTT_CTRL_TEXT_BRIGHT_BLUE,   // DEBUG: 青色
    RTT_CTRL_TEXT_BRIGHT_GREEN,  // INFO: 亮绿色
    RTT_CTRL_TEXT_BRIGHT_YELLOW, // WARNING: 亮黄色
    RTT_CTRL_TEXT_BRIGHT_RED     // ERROR: 亮红色
};

extern uint32_t HAL_GetTick(void);

void rtt_log_init(void)
{
  SEGGER_RTT_Init();
  SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0,
                            SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
  SEGGER_RTT_ConfigDownBuffer(0, NULL, NULL, 0,
                              SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);
  //   timestamp_cb = hal_systick_timestamp;
}

void rtt_log(LogLevel level, const char *format, ...)
{
  const int buffer_index = 0;
  uint32_t time_ms = HAL_GetTick();
  uint32_t seconds = time_ms / 1000;
  uint32_t ms = time_ms % 1000;
  uint32_t minutes = seconds / 60;
  SEGGER_RTT_printf(buffer_index, "[%02lu:%02lu.%03lu]", minutes % 60,
                    seconds % 60, ms);
  SEGGER_RTT_printf(buffer_index, "%s", level_colors[level]);

  SEGGER_RTT_printf(buffer_index, "%s", level_prefixes[level]);

  va_list args;
  va_start(args, format);
  SEGGER_RTT_vprintf(buffer_index, format, &args);
  va_end(args);
  SEGGER_RTT_printf(buffer_index, "%s\r\n", RTT_CTRL_RESET);
}
