#ifndef __LOGN_H___
#define __LOGN_H___

#ifdef __cplusplus
extern "C"
{
#endif

#define LOGN_PRINTF(...) rt_kprintf(__VA_ARGS__)

#if defined(RT_USING_ULOG)
#include <ulog.h>
#else
#define LOG_LVL_ERROR   0
#define LOG_LVL_WARNING 1
#define LOG_LVL_INFO    2
#define LOG_LVL_DBG     3

#ifdef LOG_TAG
#undef DBG_TAG
#define DBG_TAG LOG_TAG
#else
#define LOG_TAG DGB_TAG
#endif // LOG_TAG

#ifdef RT_DEBUG

#ifdef LOG_LVL
#undef DBG_LVL
#define DBG_LVL LOG_LVL
#else
#define LOG_LVL DBG_LVL
#endif // LOG_LVL

#include <rtdbg.h>
#else
#define LOGN_ENABLE
#endif // RT_DEBUG
#endif // !RT_USING_ULOG

#if (LOG_LVL < LOG_LVL_DBG)
#define LOG0(fmt, ...)
#define LOG1(fmt, ...)
#define LOG2(fmt, ...)
#define LOG3(fmt, ...)
#define LOG4(fmt, ...)
#define LOG5(fmt, ...)
#define LOG6(fmt, ...)
#define LOG7(fmt, ...)
#define LOG10(fmt, ...)
#define LOG11(fmt, ...)
#define LOG12(fmt, ...)
#define LOG13(fmt, ...)
#define LOG14(fmt, ...)
#define LOG15(fmt, ...)
#define LOG16(fmt, ...)
#define LOG17(fmt, ...)
#else

/**
 * CSI(Control Sequence Introducer/Initiator) sign
 * more information on https://en.wikipedia.org/wiki/ANSI_escape_code
 */
#define CSI_START   "\033["
#define CSI_END     "\033[0m"
/* output log front color */
#define F_BLACK     "30m"
#define F_RED       "31m"
#define F_GREEN     "32m"
#define F_YELLOW    "33m"
#define F_BLUE      "34m"
#define F_MAGENTA   "35m"
#define F_CYAN      "36m"
#define F_WHITE     "37m"
/* output log backgroup color */
#define B_BLACK     "40m"
#define B_RED       "41m"
#define B_GREEN     "42m"
#define B_YELLOW    "43m"
#define B_BLUE      "44m"
#define B_MAGENTA   "45m"
#define B_CYAN      "46m"
#define B_WHITE     "47m"
// 亮前景色
#define F_GRAY      "90m"
#define F_B_BLACK   "90m"
#define F_B_RED     "91m"
#define F_B_GREEN   "92m"
#define F_B_YELLOW  "93m"
#define F_B_BLUE    "94m"
#define F_B_MAGENTA "95m"
#define F_B_CYAN    "96m"
#define F_B_WHITE   "97m"
// 亮背景色
#define B_GRAY      "100m"
#define B_B_BLACK   "100m"
#define B_B_RED     "101m"
#define B_B_GREEN   "102m"
#define B_B_YELLOW  "103m"
#define B_B_BLUE    "104m"
#define B_B_MAGENTA "105m"
#define B_B_CYAN    "106m"
#define B_B_WHITE   "107m"

#define SET_COLOR(c, s) CSI_START c s CSI_END
#ifdef RT_USING_ULOG
#define logn_line(color_n, fmt, ...) ulog_d(LOG_TAG, SET_COLOR(color_n, fmt), ##__VA_ARGS__)
#else //  !RT_USING_ULOG

#if (DBG_LEVEL >= DBG_LOG || defined(LOGN_ENABLE))

#ifndef RT_DEBUG
#define dbg_log_line(lvl, color_n, fmt, ...) LOGN_PRINTF(SET_COLOR(color_n, lvl) fmt "\n", ##__VA_ARGS__);
#endif // !RT_DEBUG

#define logn_line(color_n, fmt, ...) dbg_log_line("N", 0, SET_COLOR(color_n, fmt), ##__VA_ARGS__)

#else // !(DBG_LEVEL >= DBG_LOG)
#define logn_line(...)
#endif //  (DBG_LEVEL >= DBG_LOG)

#endif //  RT_USING_ULOG

#ifdef USE_LOG0
#define LOG0(fmt, ...) logn_line("30;100m", fmt, ##__VA_ARGS__)
#else
#define LOG0(fmt, ...)
#endif // USE_LOG0
#ifdef USE_LOG1
#define LOG1(fmt, ...) logn_line(F_RED, fmt, ##__VA_ARGS__)
#else
#define LOG1(fmt, ...)
#endif // USE_LOG1
#ifdef USE_LOG2
#define LOG2(fmt, ...) logn_line(F_GREEN, fmt, ##__VA_ARGS__)
#else
#define LOG2(fmt, ...)
#endif // USE_LOG2
#ifdef USE_LOG3
#define LOG3(fmt, ...) logn_line(F_YELLOW, fmt, ##__VA_ARGS__)
#else
#define LOG3(fmt, ...)
#endif // USE_LOG3
#ifdef USE_LOG4
#define LOG4(fmt, ...) logn_line(F_BLUE, fmt, ##__VA_ARGS__)
#else
#define LOG4(fmt, ...)
#endif // USE_LOG4
#ifdef USE_LOG5
#define LOG5(fmt, ...) logn_line(F_MAGENTA, fmt, ##__VA_ARGS__)
#else
#define LOG5(fmt, ...)
#endif // USE_LOG5
#ifdef USE_LOG6
#define LOG6(fmt, ...) logn_line(F_CYAN, fmt, ##__VA_ARGS__)
#else
#define LOG6(fmt, ...)
#endif // USE_LOG6
#ifdef USE_LOG7
#define LOG7(fmt, ...) logn_line(F_WHITE, fmt, ##__VA_ARGS__)
#else
#define LOG7(fmt, ...)
#endif // USE_LOG7

#ifdef USE_LOG10
#define LOG10(fmt, ...) logn_line(F_GRAY, fmt, ##__VA_ARGS__)
#else
#define LOG10(fmt, ...)
#endif // USE_LOG10
#ifdef USE_LOG11
#define LOG11(fmt, ...) logn_line(F_B_RED, fmt, ##__VA_ARGS__)
#else
#define LOG11(fmt, ...)
#endif // USE_LOG11
#ifdef USE_LOG12
#define LOG12(fmt, ...) logn_line(F_B_GREEN, fmt, ##__VA_ARGS__)
#else
#define LOG12(fmt, ...)
#endif // USE_LOG12
#ifdef USE_LOG13
#define LOG13(fmt, ...) logn_line(F_B_YELLOW, fmt, ##__VA_ARGS__)
#else
#define LOG13(fmt, ...)
#endif // USE_LOG13
#ifdef USE_LOG14
#define LOG14(fmt, ...) logn_line(F_B_BLUE, fmt, ##__VA_ARGS__)
#else
#define LOG14(fmt, ...)
#endif // USE_LOG14
#ifdef USE_LOG15
#define LOG15(fmt, ...) logn_line(F_B_MAGENTA, fmt, ##__VA_ARGS__)
#else
#define LOG15(fmt, ...)
#endif // USE_LOG15
#ifdef USE_LOG16
#define LOG16(fmt, ...) logn_line(F_B_CYAN, fmt, ##__VA_ARGS__)
#else
#define LOG16(fmt, ...)
#endif // USE_LOG16
#ifdef USE_LOG17
#define LOG17(fmt, ...) logn_line(F_B_WHITE, fmt, ##__VA_ARGS__)
#else
#define LOG17(fmt, ...)
#endif // USE_LOG17

#ifndef USE_LOG_D
#undef LOG_D
#define LOG_D(...)
#endif // USE_LOG_D
#endif

#define IS_USE_LOGN(n) ((defined(USE_LOG##n)) && (LOG_LVL >= LOG_LVL_DBG))

#ifdef __cplusplus
}
#endif

#endif // !__LOGN_H___