/**
*@file    sr_log.h
*@brief   LOG组件
*@details 提供LOG组件数据结构和API接口
*@copyright Copyright (c) 2024 lierda. All rights reserved.
*@author  Lierda-RDC
*@date    2024-05-07
*@example ZhaoyangSDK\example\component\log_example.c
*/

#ifndef _SR_LOG_H
#define _SR_LOG_H

#include "sr_config.h"
#include "sr_stddef.h"
#include "sr_bsp_log.h"


#ifndef SR_LOG_COMPILE_LEVEL
#define SR_LOG_COMPILE_LEVEL   (7)     /*!<log代码编译等级，范围[0~7]：<=该等级的LOG才会被编译； -1：都不编译*/
#endif

#ifndef SR_LOG_LEVEL_DEFAULT
#define SR_LOG_LEVEL_DEFAULT   INFO    /*!<默认的log输出等级，范围[0~7]：<=该等级的LOG才会输出*/
#endif

//LOG打印函数内部发送缓存大小
#ifndef SR_LOG_UART_TBUF_LEN
#define SR_LOG_UART_TBUF_LEN   256
#endif

//LOG打印函数内部发送缓存大小
#ifndef SR_LOG_UART_RBUF_LEN
#define SR_LOG_UART_RBUF_LEN   256
#endif



/*!<颜色控制符定义*/
#define NONE       "\033[0m"
#define BLACK      "\033[0;30m"
#define L_BLACK    "\033[1;30m"
#define RED        "\033[0;31m"
#define L_RED      "\033[1;31m"
#define GREEN      "\033[0;32m"
#define L_GREEN    "\033[1;32m"
#define BROWN      "\033[0;33m"
#define YELLOW     "\033[1;33m"
#define BLUE       "\033[0;34m"
#define L_BLUE     "\033[1;34m"
#define PURPLE     "\033[0;35m"
#define L_PURPLE   "\033[1;35m"
#define CYAN       "\033[0;36m"
#define L_CYAN     "\033[1;36m"
#define GRAY       "\033[0;37m"
#define WHITE      "\033[1;37m"

#define _TOSTINNG(s) #s       /*!<变量转字符串*/

/**
 * @brief 日志级别枚举
 */
typedef enum SR_LOG_LEVEL
{
  EMERG  = 0, /*!<紧急情况。用于系统崩溃、无法恢复的故障等情况*/
  ALERT  = 1, /*!<警报。系统遇到了严重问题，需要立即采取行动*/
  CRIT   = 2, /*!<关键或严重错误。系统遇到了一个严重错误，可能影响系统的稳定性或功能*/
  ERR    = 3, /*!<错误。系统出现了一些错误，可能导致某些功能无法正常工作，但系统仍然能继续运行*/
  WARN   = 4, /*!<警告。暗示一些可能潜在问题，但不会对系统造成实质性影响*/
  NOTICE = 5, /*!< 通知。系统的某些事件或状态发生变化，需要关注*/
  INFO   = 6, /*!<信息。用于显示系统的正常的运行情况*/
  DEBUG  = 7, /*!<调试。*/
} SR_LOG_LVL_E;


#ifdef SR_USE_LOG


extern char *g_levelColor[8];  //颜色数组
extern int _LogPrintf(uint8_t level, char *fmt, ...);  //原始LOG打印

#define _LOG(level, fmt, ...) _LogPrintf(level, "%s"                        \
                                                  "%s"                        \
                                                  "(%s:%d) " NONE fmt "\r\n", \
                                           g_levelColor[level], _TOSTINNG([level]), __func__, __LINE__, ##__VA_ARGS__)


/**基于_LOG()封装了一些宏，可通过条件编译，控制LOG代码是否被编译**/
#define SR_LOG_EMERG(fmt, ...)   _LOG(EMERG,fmt, ##__VA_ARGS__)
#define SR_LOG_ALERT(fmt, ...)   _LOG(ALERT,fmt, ##__VA_ARGS__)
#define SR_LOG_CRIT(fmt, ...)    _LOG(CRIT,fmt, ##__VA_ARGS__)
#define SR_LOG_ERR(fmt, ...)     _LOG(ERR,fmt, ##__VA_ARGS__)
#define SR_LOG_WARN(fmt, ...)    _LOG(WARN,fmt, ##__VA_ARGS__)
#define SR_LOG_NOTICE(fmt, ...)  _LOG(NOTICE,fmt, ##__VA_ARGS__)
#define SR_LOG_INFO(fmt, ...)    _LOG(INFO,fmt, ##__VA_ARGS__)
#define SR_LOG_DEBUG(fmt, ...)   _LOG(DEBUG,fmt, ##__VA_ARGS__)


/**
 * @brief LOG打印函数
 * 支持级别过滤
 *
 * @param[in] level  日志级别，SR_LOG_LVL_E类型
 * @param[in] fmt    格式化字符串
 * @param[in] ...    可变参数
 *
 * @return >=0成功，负值失败
 */
#define SR_LOG(level,fmt, ...)   SR_LOG_##level(fmt, ##__VA_ARGS__)


/**
 * @brief LOG日志输出级别设置
 *
 * @param[in] level  日志显示级别，SR_LOG_LVL_E类型
 *
 * @return  无
 */
 
void SR_LogSetLevel(SR_LOG_LVL_E level);

/**
 * @brief 获取当前LOG日志输出级别
 *
 *
 * @return  LOG输出级别
 */
uint8_t SR_LogGetLevel(void);



/**
 * @brief printf打印
 *
 * @param[in] fmt   格式化字符串
 * @param[in] ...   可变参数
 *
 * @return  >0:实际打印长度         负值：打印失败
 */
int SR_Printf(const char *fmt, ...);  


#define SR_PRINTF(fmt, argv...) SR_Printf(fmt "\r\n", ##argv)  /*!< 打印函数宏定义，末尾加了\r\n */


/**
 * @brief LOG串口发送指定长度数据
 *
 * @param[in] buf  带发送数据缓冲区
 * @param[in] len  待发送的数据量
 *
 * @return 成功：>0,实际发送的字节数  失败：负值错误码
 */
int SR_LogUartWrite(uint8_t *buf, uint32_t len);

/**
 * @brief LOG串口初始化
 * @note  默认在sr_startup.c（即SDK启动阶段）中被调用
 *
 * @return  无
 */
void SR_LogUartInit(void);





/*以下通过条件编译，控制LOG代码是否为空*/
#if SR_LOG_COMPILE_LEVEL < 7
#undef SR_LOG_DEBUG
#define SR_LOG_DEBUG(fmt, ...)  
#endif

#if SR_LOG_COMPILE_LEVEL < 6
#undef SR_LOG_INFO
#define SR_LOG_INFO(fmt, ...) 
#endif

#if SR_LOG_COMPILE_LEVEL < 5
#undef SR_LOG_NOTICE
#define SR_LOG_NOTICE(fmt, ...) 
#endif

#if SR_LOG_COMPILE_LEVEL < 4
#undef SR_LOG_WARN
#define SR_LOG_WARN(fmt, ...)
#endif

#if SR_LOG_COMPILE_LEVEL < 3
#undef SR_LOG_ERR
#define SR_LOG_ERR(fmt, ...)
#endif

#if SR_LOG_COMPILE_LEVEL < 2
#undef SR_LOG_CRIT
#define SR_LOG_CRIT(fmt, ...)
#endif

#if SR_LOG_COMPILE_LEVEL < 1
#undef SR_LOG_ALERT
#define SR_LOG_ALERT(fmt, ...)
#endif

#if SR_LOG_COMPILE_LEVEL < 0
#undef SR_LOG_EMERG
#define SR_LOG_EMERG(fmt, ...)
#endif

#else   //不使用LOG组件


#define SR_LOG(level, fmt, ...)

#define SR_LOG_EMERG(fmt, ...)   
#define SR_LOG_ALERT(fmt, ...)   
#define SR_LOG_CRIT(fmt, ...)   
#define SR_LOG_ERR(fmt, ...)     
#define SR_LOG_WARNING(fmt, ...)    
#define SR_LOG_NOTICE(fmt, ...)  
#define SR_LOG_INFO(fmt, ...)   
#define SR_LOG_DEBUG(fmt, ...)  


#define SR_PRINTF(fmt, argv...)
#define SR_Printf(fmt, argv...)


#endif

#endif
