/**
@file log.h
@brief This file contains the declarations of log interfaces and data structures. LogManager provides log data asynchronous output function and the ability to obtain input debugging commands. Log data is also sent to the AP for saving. Please refer to log_creat.h for specific configuration instructions.
- LOG_OUTPUT_DEBUG is the log data output interface.
- LOG_GETINPUTSTRING_PROCESS is the debug cmd input interface.
- There is an sample in hmidemo.
      
## changelog ##
______
Data        | Vesion   | Change Description
------------|----------|-------------------------------------
20221104    | 1.0      | First release.
20230421    | 1.1      | 1. Modify interface description. \n 2. Add an introduction to LogManager.
20230516    | 1.2      | Add macro definition description.
*/

/********************************************************************************************
Multi-Inlcude-Prevent Section                                  
********************************************************************************************/
#ifndef LOG_CONFIG_H
#define LOG_CONFIG_H

/********************************************************************************************
Debug Switch Definition Section                             
********************************************************************************************/

/********************************************************************************************
Include File Section                                     
********************************************************************************************/
#include "main.h"
//#include "log_type.h"

/********************************************************************************************
Macro Definition Section                                       
********************************************************************************************/
#define SAF_TRUE		1u
#define SAF_FALSE	0u

/**
@brief The maximum number of characters for the echo command.
*/
#define SHELL_BUFFER_LENGTH	             (100u)  
/**
@brief Maximum number of debug instructions.
*/
#define MAXDEGPARAMNUM                   (6u)
/**
@brief Maximum number of characters per instructions.
*/
#define MAXSINGELSTRINGLENGTH            (30u)
 

/**
@brief Log creates related macro definitions.
*/ 
#define LOG_WRITE_IDLE                   (0u)
#define SIMPLE_FILTER			         700
#define BUILD_NAME(name)	             #name
#define BUILD_CMD_NAME(cmd)              #cmd
#define LOG_BUILD_CATEGORY(name)               name##Category
#define INPUT_FUNCTION(name,str)         vGetString((name),(str))
#define BUILD_RB_BUFFER(name)            g_ucRB##name##Buff[256] = {0};
#define BUFFER_CMD_BUILD(name,size)      g_ucLog##name##Buff[(size)] = {0};   //buffer


#define MK_CATEGORY(category, szname, gate) \
LOG_CATEGORY category = \
{\
	.name = (uint8_t *)(szname),\
	.prority_gate = (gate),\
	.init_flag = 0,\
};



/**
@brief Processing if initialization.
@param SELECT [in] Selected uart channel.
@param TYPE [in] Uart type (FuSa uart or Peri uart).
*/ 
#define LOG_INIT_CONFIG(SELECT,TYPE) \
	uint8_t ucUartChSelect = (SELECT); \
	uint8_t ucUartChType = (TYPE);

/**
@brief Create a buffer.
@param name [in] The name of the module, keep your name short.
@param size [in] Buffer size, the size ranges from 1KB to 5KB.
@note 
  For an example of the interface, see the log_creat.c.
*/ 
#define LOG_BUFF_CREAT(name,size)  \
    uint8_t BUFFER_CMD_BUILD(name,size); \
  	uint8_t BUILD_RB_BUFFER(name); \
    uint16_t g_usBuff##name##SIZE = size;\
    MK_CATEGORY(name##Category,BUILD_NAME(name), SIMPLE_FILTER);
   

/**
@brief Configure log management for related functions. 
@param name [in] The name of the module.
@note 
- The name is the same as that in the creation buffer.
- For an example of the interface, see the log_creat.c.
*/    

#define CRATELOGTABLE(name)   \
	{\
		(uint8_t *)BUILD_NAME(name),\
		(uint8_t *)BUILD_CMD_NAME(name),\
		SAF_FALSE,\
		&g_usBuff##name##SIZE,\
		0,\
		1,\
		LOG_WRITE_IDLE,\
		g_ucRB##name##Buff,\
		g_ucLog##name##Buff,\
		{0},\
		{0},\
		{0}\
	}



/**
@brief Declare log processing. 
@param name [in] The name of the module.       
@note 
- The name is the same as that of the application buffer.
- For an example of the interface, see the log_creat.h.
*/
#define LOG_DECLARATION(name)                     extern LOG_CATEGORY name##Category

                             
/**
@brief asynchronous log output. 
@param name [in] The name of the module.
@param ... [in] The log data.
*/
#define LOG_OUTPUT_DEBUG(name,...)                      vLOG_DEBUG(&LOG_BUILD_CATEGORY(name),(const uint8_t *)__VA_ARGS__)

/**
@brief Get debug cmd.
@param name [in] The name of the module.
@param data [in] Cmd buffer.
@param length [in] Buffer size.
*/
#define LOG_GETINPUTSTRING_PROCESS(name,data,length)     vGetInputString((uint8_t *)BUILD_NAME(name),(data),(length))

/********************************************************************************************
Structure Type Declaration Section                           
********************************************************************************************/
#if 0
typedef enum
{
	CATE_UNINITED = 0,
	CATE_INITED,
} INIT_FLAG;
#endif
typedef struct
{
	uint8_t m_initFlag;
	uint8_t	*m_pdata;				/*pointer to queue*/
	uint8_t	*m_phead;				/*pointer to head*/
	uint8_t	*m_ptail;				/*pointer to end*/
	uint32_t m_max_size;			/*buffer size*/
	uint32_t m_free_size;			/*free buffer size*/
	uint32_t m_len;
	uint8_t	 m_error;
	uint16_t m_sem;
} RB;

typedef struct
{
	const uint8_t *logname; 
	const uint8_t *logcmd;
	boolean open_flag;
	uint16_t *buffsize;
	uint8_t isvalid;
	uint16_t SEM_ID_LogRb;
	uint8_t log_status_flag;
	uint8_t *LOG_RBbuf;
	uint8_t *RB_LogData;
	RB RB_Log;
    RB RB_cpy;
    RB RB_AP_cpy;	
}Log_Buffer_Param; 

typedef struct
{
    const uint8_t *name;
    int32_t prority_gate;
    uint8_t init_flag;	
}LOG_CATEGORY;
typedef struct
{
	Log_Buffer_Param *log_cfg;
	uint8_t cfg_size;
}Log_Cfg_t;
/********************************************************************************************
Prototype Declaration Section                                 
********************************************************************************************/

extern uint8_t ucUartChSelect; 
extern uint8_t ucUartChType;


void vLogInit(void);
void vLOG_DEBUG(LOG_CATEGORY * category, const uint8_t *format, ...);
void vGetInputString(uint8_t *name,uint8_t *str,uint8_t length);

extern Log_Cfg_t g_axLog_Cfg[1];

/**
@brief This function is called periodically, you can add debugging command processing functions. Because the triggered task cannot periodically \n
call the LOG_GETINPUTSTRING_PROCESS(name, data, length) to get debugging instructions, if the task is not triggered, the debugging command cannot be obtained.
@return void
@note 
 Each module defines a separate debug handler function and calls it in vCycleGetDebugCmd().
*/
void vCycleGetDebugCmd(void);
void vSystemBootReady(void);

#endif
