#ifndef __HX_DEBUG_H__
#define __HX_DEBUG_H__

#include <stdio.h>

#define ALL				0

#define TVSDK_DBG_ID	200
#define TEST_DBG_ID		201

#define MAX_DEBUG_MODULE_ID_COUNT 256

#define DBG_ERROR				0
#define DBG_WARNING			1
#define DBG_INFO				2
#define DBG_VERBOSE			3
#define DBG_MOREVERBOSE		4
#define DBG_DEBUG				5
#define DBG_VERBOSEDEBUG	6

extern int verbosity_map[];

void hexdump(char * title, unsigned char * data, int len);

#ifdef THIN_DEBUG
	#ifdef _DEBUG
		#define	ENABLED_LEVEL DBG_VERBOSEDEBUG
	#else
		// On release build, let the gcc remove unwanted debug message.
		#define	ENABLED_LEVEL DBG_WARNING
	#endif

	#define dprintf(module_id, level, fmt...) \
		do { \
			if (level <= ENABLED_LEVEL && level <= verbosity_map[module_id]) \
				fprintf(stderr, fmt); \
		} while (0)
#else
	#define dprintf(module_id, level, fmt...) \
		do { \
			if (module_id < MAX_DEBUG_MODULE_ID_COUNT) { \
				if (level <= verbosity_map[module_id])	{ \
					fprintf(stderr,"\033[32m");   \
					fprintf(stderr, fmt);	\
					fprintf(stderr,"\033[0m"); }  \
			} \
			else { \
				fprintf(stderr, "Invalid module_id for DEBUG MESSAGE\n"); \
			} \
		} while (0)
#endif

#define DBG_PREFIX ""

#ifdef TARGETNAME
	#define dpprintf(module_id, level, fmt, args...) \
		dprintf(module_id, level, TARGETNAME " " DBG_PREFIX "%s:%d " fmt, __func__, __LINE__ , ##args)
#else
	#define dpprintf(module_id, level, fmt, args...) \
		dprintf(module_id, level, DBG_PREFIX " %s:%d " fmt, __func__, __LINE__ , ##args)
#endif

#define deprintf(module_id, level, fmt, args...) \
	dprintf(module_id, level, DBG_PREFIX "ERROR: %s:%d " fmt, __func__, __LINE__ , ##args)
#define dwprintf(module_id, level, fmt, args...) \
	dprintf(module_id, level, DBG_PREFIX "WARNING: %s:%d " fmt, __func__, __LINE__ , ##args)

#define fatal(module_id, fmt, args...) do { dpprintf(module_id, -1, "FATAL: " fmt , ##args); exit(1); } while(0)
#define error(module_id, msg...) dprintf(module_id, 0, "ERROR: " msg)
#define errorn(module_id, msg...) deprintf(module_id, 0, msg)
#define error_errno(module_id, msg) dprintf(module_id, 0, "ERROR[%s:%d] " msg ": %d %m\n", __FUNCTION__, __LINE__, errno)
#define warning(module_id, msg...) dprintf(module_id, 1, "WARNING: " msg)
#define warningn(module_id, msg...) dwprintf(module_id, 1, msg)
#define info(module_id, msg...) dprintf(module_id, 2, msg)
#define infon(module_id, msg...) dpprintf(module_id, 2, msg)
#define verbose(module_id, msg...) dprintf(module_id, 3, msg)
#define verbosen(module_id, msg...) dpprintf(module_id, 3, msg)
#define moreverbose(module_id, msg...) dprintf(module_id, 4, msg)
#define moreverbosen(module_id, msg...) dpprintf(module_id, 4, msg)
#define debug(module_id, msg...) dprintf(module_id, 5, msg)
#define debugn(module_id, msg...) dpprintf(module_id, 5, msg)
#define verbosedebug(module_id, msg...) dpprintf(module_id, 6, msg)
#define verbosedebugn(module_id, msg...) dpprintf(module_id, 6, msg)

#define INIT_CHECK_TIME unsigned long start_time, last_time, current_time;

#define START_CHECK_TIME \
	start_time = get_time_in_milisecond(); last_time = start_time; 

#define CHECK_TIME \
	current_time = get_time_in_milisecond(); \
	printf("-------------->[%5d] ELAPSED TIME: %lu\n", \
			__LINE__, current_time-last_time); \
	last_time = current_time;

#endif
