/*
 * @file hv_vos_Log.h
 * @brief Header file of vos log.
 *
 * @verbatim
 * ==============================================================================
 *                        ##### How to use #####
 * ==============================================================================
 * (+) Use ()
 *
 * @endverbatim
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2023-03-01
 */



#ifndef _HV_VOS_LOG_H
#define _HV_VOS_LOG_H

#include "hv_vos_Types.h"

VOS_EXTERN_C_BEGIN

/** @defgroup VOS_LOG VOS_LOG
 *  VOS log functions
 *  @{
 */
#define HV_LOG_LEVEL_VERBOSE    0
#define HV_LOG_LEVEL_INFO       1
#define HV_LOG_LEVEL_WARN       2
#define HV_LOG_LEVEL_ERROR      3
#define HV_LOG_LEVEL_FATAL      4
#define HV_LOG_LEVEL_ALWAYS     5
#define HV_LOG_LEVEL_NONE       6


#define HV_LOG_SHOW_TASK_ID     0x0001
#define HV_LOG_SHOW_FILENAME    0x0002
#define HV_LOG_SHOW_FUNCTION    0x0004
#define HV_LOG_SHOW_TIMESTAMP   0x0008
#define HV_LOG_SHOW_LINE        0x0010

#define HV_LOG_ENABLED(lvl)     ((lvl) >= _HV_LOG_OUTPUT_LEVEL)
#define HV_LOG_ENABLED_VERBOSE  HV_LOG_ENABLED(HV_LOG_LEVEL_VERBOSE)
#define HV_LOG_ENABLED_INFO     HV_LOG_ENABLED(HV_LOG_LEVEL_INFO)
#define HV_LOG_ENABLED_WARN     HV_LOG_ENABLED(HV_LOG_LEVEL_WARN)
#define HV_LOG_ENABLED_ERROR    HV_LOG_ENABLED(HV_LOG_LEVEL_ERROR)
#define HV_LOG_ENABLED_FATAL    HV_LOG_ENABLED(HV_LOG_LEVEL_FATAL)
#define HV_LOG_ON(lvl) HV_LOG_ENABLED(lvl)

#ifdef HV_SCALER_DEBUG_VERSION
extern UINT32 g_uiLogOutputLevel;
#define _HV_LOG_OUTPUT_LEVEL HV_LOG_LEVEL_INFO
#else
#define _HV_LOG_OUTPUT_LEVEL HV_LOG_LEVEL_ERROR
#endif

#ifdef HV_CONFIG_ENABLE_PRINT
extern void Hv_Vos_LOG_Write(int level, int raw, const char *func,
                         int line,
                         const char *fmt, ...);
#else
#define Hv_Vos_LOG_Write(...)
#endif

#define HV_LOG_WRITE(level, ...)                                                                                                \
    do {                                                                                                                                                \
        if (HV_LOG_ON(level)){                                                                                                  \
            Hv_Vos_LOG_Write(level, 0, __FUNCTION__, __LINE__, __VA_ARGS__); \
        }                                                                                                                                               \
    } while (0)

#define HV_RAW_LOG_WRITE(level, ...)                                                                                            \
    do {                                                                                                                                                \
        if (HV_LOG_ON(level)){                                                                                                  \
            Hv_Vos_LOG_Write(level, 1,  __FUNCTION__, __LINE__, __VA_ARGS__); \
        }                                                                                                                                               \
    } while (0)
 

#define HV_LOGV(...) HV_LOG_WRITE(HV_LOG_LEVEL_VERBOSE, __VA_ARGS__)
#define HV_LOGI(...) HV_LOG_WRITE(HV_LOG_LEVEL_INFO, __VA_ARGS__)
#define HV_LOGW(...) HV_LOG_WRITE(HV_LOG_LEVEL_WARN, __VA_ARGS__)
#define HV_LOGE(...) HV_LOG_WRITE(HV_LOG_LEVEL_ERROR, __VA_ARGS__)
#define HV_LOGF(...) HV_LOG_WRITE(HV_LOG_LEVEL_FATAL, __VA_ARGS__)
#define HV_LOGA(...) HV_LOG_WRITE(HV_LOG_LEVEL_ALWAYS, __VA_ARGS__)

#define HV_RAW_LOGV(...) HV_RAW_LOG_WRITE(HV_LOG_LEVEL_VERBOSE, __VA_ARGS__)
#define HV_RAW_LOGI(...) HV_RAW_LOG_WRITE(HV_LOG_LEVEL_INFO, __VA_ARGS__)
#define HV_RAW_LOGW(...) HV_RAW_LOG_WRITE(HV_LOG_LEVEL_WARN, __VA_ARGS__)
#define HV_RAW_LOGE(...) HV_RAW_LOG_WRITE(HV_LOG_LEVEL_ERROR, __VA_ARGS__)
#define HV_RAW_LOGF(...) HV_RAW_LOG_WRITE(HV_LOG_LEVEL_FATAL, __VA_ARGS__)
#define HV_RAW_LOGA(...) HV_RAW_LOG_WRITE(HV_LOG_LEVEL_ALWAYS, __VA_ARGS__)


void Hv_Vos_LOG_DumpBuffer(const char *func,
                        int line, const char *name, const void *buf, int buf_length);

#define HV_LOG_BUF(level, ...)  \
        do {\
                if (HV_LOG_ON(level)){  \
                        Hv_Vos_LOG_DumpBuffer(__FUNCTION__, __LINE__, __VA_ARGS__);      \
                }\
        } while (0)

#define HV_LOG_BUF_INFO(...)    HV_LOG_BUF(HV_LOG_LEVEL_INFO, __VA_ARGS__)
#define HV_LOG_BUF_VERBOSE(...) HV_LOG_BUF(HV_LOG_LEVEL_VERBOSE, __VA_ARGS__)

void Hv_Vos_LOG_SetLevel(int level);
void Hv_Vos_LOG_SetFlag(UINT32 flag);
void Hv_Vos_FlushLogBuf(void);
/** @} */
VOS_EXTERN_C_END

#endif
