/*
 * @Description: 日志模块-svc层
 * @Author: yangsw
 * @Date: 2021-05-18 16:59:48
 * @LastEditTime: 2024-01-10 11:00:49
 * @LastEditors: LiDa
 * @Reference: 
 */
#include "svc_log.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "../../factory/svc/svc_factory.h"
#if LOG_FUNC_ENABLE
static char str[100];
#endif
static S_Log_Uart s_log_uart;


/**
 * @brief: 日志打印输出
 * @return {void}
 * @note: 只有打印等级高于设置的当前模块打印等级时才会打印
 * 不可打印超过数组str长度的数据，否则将会发生异常
 * @see: printf
 * @param {unsigned int} level 打印等级
 * @param {char} *fmt
 */
void Svc_Log_Printf(unsigned int level,char *fmt,...){
	#if LOG_FUNC_ENABLE
    // char str[256];
    char *buffer = NULL;
    int i;
    va_list v1; 
    if(GW_LOG_LEVEL<level){
        return;
    }
    char* str=(char*)malloc(512);
    if(str==NULL){
        return;
    }
    memset(str,0x00,sizeof(str));

    switch (level&0xFF)
    {
    case LOG_ERROR:
        i=8;
        memcpy(str,"\r\nERROR ",i);
        buffer=str+i;
        break;
    case LOG_WARNING:
        i=10;
        memcpy(str,"\r\nWARNING ",i);
        buffer=str+i;
        break;
    case LOG_INFO:
        i=7;
        memcpy(str,"\r\nINFO ",i);
        buffer=str+i;
        break;
    case LOG_DEBUG:
        i=8;
        memcpy(str,"\r\nDEBUG ",i);
        buffer=str+i;
        break;
    default:
        i=0;
        buffer=str+i;
        break;
    }
    va_start(v1,fmt);
    Bsp_Iwdg_Feed();//喂狗<<  
    vsprintf(buffer,fmt,v1);//将参数fmt、ap指向的可变参数一起转换成格式化字符串，放string数组中，其作用同sprintf（），只是参数类型不同  
    Bsp_Log_Send_Str((gw_u8*)str);  
    Bsp_Iwdg_Feed();//喂狗<<   
    va_end(v1);    //ap付值为0，没什么实际用处，主要是为程序健壮性  
    if(str!=NULL){
        free(str);
        str=NULL;
    }
	#endif
}

void Svc_FactoryLog_Printf(unsigned int level,char *fmt,...){
    char *buffer = NULL;
    int i;
    va_list v1; 
    if(GW_LOG_LEVEL<level){
        return;
    }
    char* str=(char*)malloc(512);
    if(str==NULL){
        return;
    }
    memset(str,0x00,sizeof(str));

    switch (level&0xFF)
    {
    case LOG_ERROR:
        i=8;
        memcpy(str,"\r\nERROR ",i);
        buffer=str+i;
        break;
    case LOG_WARNING:
        i=10;
        memcpy(str,"\r\nWARNING ",i);
        buffer=str+i;
        break;
    case LOG_INFO:
        i=7;
        memcpy(str,"\r\nINFO ",i);
        buffer=str+i;
        break;
    case LOG_DEBUG:
        i=8;
        memcpy(str,"\r\nDEBUG ",i);
        buffer=str+i;
        break;
    default:
        i=0;
        buffer=str+i;
        break;
    }
    va_start(v1,fmt);
    Bsp_Iwdg_Feed();//喂狗<<  
    vsprintf(buffer,fmt,v1);//将参数fmt、ap指向的可变参数一起转换成格式化字符串，放string数组中，其作用同sprintf（），只是参数类型不同  
    Bsp_Log_Send_Str((gw_u8*)str);  
    Bsp_Iwdg_Feed();//喂狗<<   
    va_end(v1);    //ap付值为0，没什么实际用处，主要是为程序健壮性  
    if(str!=NULL){
        free(str);
        str=NULL;
    }    
}


/**
 * @brief: 日志模块初始化
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Log_Init(void){
    #if LOG_TESTFAC_ENABLE
        Bsp_Log_Tx_Init();
    #else
        Bsp_Log_Tx_Init();
    #endif
}

/**
 * @brief: NB串口初始化
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Log_Wake_Init(void)
{
    Bsp_Log_Tx_Init();
  // Log_Uart_Wake_Init();
}
/**
 * @brief: 将一字节数据放入接收队列
 * @return {char} 1：队列已满，0：队列未满
 * @note: 
 * @see: 
 * @param {char} data 待放入数据
 */
char Svc_Log_Uart_Put_Data_Quene(char data)
{
  s_log_uart.time_cnt=0;      //队列计数清零
  s_log_uart.time_en=1;
  if(((s_log_uart.fornt+1)%LOG_UART_RX_BUF_SIZE)==s_log_uart.rear)      //串口队列缓冲区满
  {
    //Svc_Log_Print("F\r\n");
    s_log_uart.format=1;
    return 1;
  }
  s_log_uart.RX_BUF[s_log_uart.fornt]=data;
  s_log_uart.fornt=(s_log_uart.fornt+1)%LOG_UART_RX_BUF_SIZE;
  return 0;
}

/**
 * @brief: 从队列中取出一字节数据
 * @param  {char*} data 取出的数据
 * @return {char} 1：队列为空，0：正常
 * @note: 
 * @see: 
 */
char Svc_Log_Uart_Out_data_Quene(char* data)
{
  if(s_log_uart.rear==s_log_uart.fornt)
  {
    //Svc_Log_Print("C\r\n");
    return 1;
  }
  *data=s_log_uart.RX_BUF[s_log_uart.rear];
  s_log_uart.rear=(s_log_uart.rear+1)%LOG_UART_RX_BUF_SIZE;
  return 0;
}

/**
 * @brief: 串口接收队列初始化
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Nb_Log_Quene_Init(void)
{
  s_log_uart.fornt=0;
  s_log_uart.rear=0;
  s_log_uart.time_cnt=0;
  s_log_uart.format=0;
  memset(s_log_uart.RX_BUF,0,sizeof(s_log_uart.RX_BUF));
}

/**
 * @brief: 获取队列中数据长度
 * @param  {void}
 * @return {short} 队列中数据长度
 * @note: 
 * @see: 
 */
static short Get_Buf_Length(void)
{
  // Svc_Log_Print("gprs_quene->fornt=%d\r\n",gprs_quene->fornt);
 // Svc_Log_Print("gprs_quene->rear=%d\r\n",gprs_quene->rear);
  if(s_log_uart.fornt>=s_log_uart.rear)
  {
    return s_log_uart.fornt-s_log_uart.rear;
  }
  else
  {
    return s_log_uart.fornt+LOG_UART_RX_BUF_SIZE-s_log_uart.rear;
  }
}

/**
 * @brief: 从队列中获取指定字节数的数据
 * @return {short} 实际获取字节数
 * @note: 
 * @see: 
 * @param {char} *data 存放获取数据的指针
 * @param {short} buf_len 想要获取的数据长度
 */
short Get_Log_Uart_Bytes(char *data,short buf_len)
{
  short data_len=0;
  short i=0;
  char* ptr=data;
  data_len=Get_Buf_Length();
  s_log_uart.time_cnt=0;
  s_log_uart.format=0;
  s_log_uart.time_en=0;
//  Svc_Log_Print("gprs_buf.fornt=%d\r\n",gprs_buf.fornt);
//  Svc_Log_Print("gprs_buf.rear=%d\r\n",gprs_buf.rear);
//  Svc_Log_Print("data_len=%d\r\n",data_len);

  if(data_len==0)
  {
    return 0;
  }
  for(i=0;i<data_len&&i<buf_len;i++)
  {
    Svc_Log_Uart_Out_data_Quene(ptr);
    ptr++;
  }

   return i;
}

/**
 * @brief: 自动断帧检测
 * @param  {void}
 * @return {void}
 * @note: 隔1ms检查串口是否有数据
 * @see: 
 */
void Svc_Log_get_Cnt_Add(void)         //隔1ms检查串口是否有数据
{
  if(s_log_uart.time_en==1)           //串口有数据
  {
    s_log_uart.time_cnt++;
    if(s_log_uart.time_cnt>LOG_UART_CNT_MAX)         //接收自动断帧
    {
      s_log_uart.time_cnt=0;
      s_log_uart.format++;
      s_log_uart.time_en=0;
    }
  }
}

/**
 * @brief: 判断一帧数据是否接收完成
 * @param  {void}
 * @return {char} 1：一帧数据收完，0：一帧数据未收完
 * @note: 
 * @see: 
 */
char Log_Is_Format(void)
{
  return s_log_uart.format;
}

/**
 * @brief: 串口接收处理
 * @param  {void}
 * @return {void}
 * @note: 
 * @see: 
 */
void Svc_Log_Uart_Recv(void){
  if(Log_Is_Format()>=1){
    gw_u16 recv_len=0;
    gw_u16 buf_len;
    s_log_uart.temp_buf=Svc_Com_Get_Buf();
    // s_log_uart.temp_buf=(gw_u8 *)malloc(NB_UART_RX_BUF_SIZE);
    if(s_log_uart.temp_buf==NULL){
        Svc_Log_Printf(LOG_ERROR,"%s->malloc fail!",__FUNCTION__);
        return ;
    }
    buf_len=LOG_UART_RX_BUF_SIZE;
    memset(s_log_uart.temp_buf,0,buf_len);
    recv_len=Get_Log_Uart_Bytes((char*)s_log_uart.temp_buf,buf_len);
    if(recv_len<LOG_UART_RX_BUF_SIZE){
        s_log_uart.temp_buf[recv_len]='\0'; //这句会破坏收的数据
      // Svc_Log_Printf(LOG_INFO,"NB recv:%s\r\n",s_log_uart.temp_buf);(有bug)
    //   Svc_Log_Print("NB recv:0x%02x\r\n",s_log_uart.temp_buf);
        // for(gw_u8 i=0;i<recv_len;i++){
        //     Svc_Log_Print("%02X ",s_log_uart.temp_buf[i]);
        // }
        // Svc_Log_Print("\r\n");
        Svc_Factory_Log_Parse(s_log_uart.temp_buf,recv_len);
    }else{
      Svc_Log_Printf(LOG_WARNING,"Factory recv len too long!\r\n");
    }
    // if(s_log_uart.temp_buf!=NULL){
    //     free(s_log_uart.temp_buf);
    //     s_log_uart.temp_buf=NULL;
    // }
  }
}
