/*
**
*/
#include "./include/tcp_debug.h"



#define TCP_MAX_OPR_LEN			16
#define TCP_MAX_OBJ_LEN			32
#define TCP_MAX_VALUE_LEN			32

#define TCP_LOG_OFF				0
#define TCP_LOG_ON					1
#define TCP_MAX_ASC_IN_LEN		128
#define TCP_MAX_ASC_OUT_LEN		4096
#define TCP_DEBUG_ID			36// menu_page2: m
#define TCP_MAX_LINE			10

/*Color Set */
#define TCP_COL_WHITE		37
#define TCP_COL_RED		31
#define TCP_COL_YELLOW		33
#define TCP_COL_GREEN		32
#define TCP_COL_BLUE		34
#define TCP_COL_BROWN		35
#define TCP_COL_MEGEN		36
#define TCP_COL_GRAY		38
#define TCP_COL_HI_WHI		58
#define TCP_COL_HI_RED		39
#define TCP_COL_HI_YEL		52
#define TCP_COL_HI_GRE		51
#define TCP_COL_HI_BLU		53
#define TCP_COL_HI_BRO		54
#define TCP_COL_HI_MEG		55
#define TCP_COL_BLACK		30
#define TCP_COL_ESC		'\033'


typedef struct
{
	u8	log_time;
	u8	log_debug;
	u8	log_warn;
	u8	log_err;
	u8	log_func;
}tcp_debug_t;

char    		tcp_ascii_in[TCP_MAX_ASC_IN_LEN];
char			tcp_ascii_out[TCP_MAX_ASC_OUT_LEN];
tcp_debug_t		tcp_debug;
static u8		TCP_VERSION[4] = {1, 0, 0, 2};		//V1.0.01 T002

static u32		debug_status_id[20] = 
{
	1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,1
};

static u32		debug_name_id[20] = 
{
	1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,2
};

static u32		debug_ascin_id[20] = 
{
	1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,3
};

static u32		debug_ascout_id[20] = 
{
	1,3,6,1,4,1,1373,1,1,2,3,1,2,TCP_DEBUG_ID + 2,4
};


const BYTE	tcp_base_id_len = 15;

static char help_menu[] =
{
	"TCP log help page\n\r\
========================================================================\n\r\
| Command             |  Remark                                        |\n\r\
========================================================================\n\r\
| help                |  help page                                     |\n\r\
| log all/none        |  display all/none logs                         |\n\r\
| log warn on/off     |  display warn logs                             |\n\r\
| log error on/off    |  display error logs                            |\n\r\
| log func on/off     |  display function logs                         |\n\r\
| log time on/off     |  display time logs                             |\n\r\
| list port[-id]      |  display tcp port resource                     |\n\r\
========================================================================\n\r\
"
};


static void tcp_print(const char *fmt, ...)
{
	va_list		ap;
	char		buf[1024];
	
	va_start(ap, fmt);
	vsprintf(buf, fmt, ap);
	
	if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN)
		strcat((char*)tcp_ascii_out, buf);
	else
		strcpy((char*)  tcp_ascii_out, buf);
	
	va_end(ap);
}

void tcp_print_time()
{
	struct timeval	tv;
	struct timezone	tz;
	struct tm		*t;
	char		timestr[128];

	if(!tcp_debug.log_time)
		return;
	
	gettimeofday(&tv, &tz);
	t = localtime(&tv.tv_sec);
	sprintf(timestr, "[%d:%d:%d.%ld] ", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec);
	tcp_print(timestr);
}

void tcp_print_debug(const char *fmt, ...)
{
	va_list		ap;
	char		buf[1024];

//	if(!tcp_debug.log_debug)
//		return ;
	va_start(ap, fmt);
	vsprintf(buf, fmt, ap);
	
	if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN)
		strcat((char*)tcp_ascii_out, buf);
	else
		strcpy((char*)tcp_ascii_out, buf);
	
	va_end(ap);
}

void tcp_print_warn(const char *fmt, ...)
{
	va_list		ap;
	char		buf[1024];
	
	if(!tcp_debug.log_warn)
		return ;
	sprintf(buf, "\33[33mWARN: ");
	
	tcp_print_time();

	va_start(ap, fmt);
	vsprintf(buf+strlen(buf), fmt, ap);
	strcat(buf, "\33[0m");
	
	if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN)
		strcat((char*)tcp_ascii_out, buf);
	else
		strcpy((char*)tcp_ascii_out, buf);
	
	va_end(ap);
}

void tcp_print_error(const char *fmt, ...)
{
	va_list		ap;
	char		buf[1024];
	
	if(!tcp_debug.log_err)
		return ;
	sprintf(buf, "\33[31mERROR: ");
	
	tcp_print_time();

	va_start(ap, fmt);
	vsprintf(buf+strlen(buf), fmt, ap);
	strcat(buf, "\33[0m");
	
	if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN)
		strcat((char*)tcp_ascii_out, buf);
	else
		strcpy((char*)tcp_ascii_out, buf);
	
	va_end(ap);
}


void tcp_print_func(const char *fmt, ...)
{
	va_list		ap;
	char		buf[1024];

	if(!tcp_debug.log_func)
		return ;

	sprintf(buf, "\33[32mFUNC: "); //, TCP_COL_GREEN	
	
	tcp_print_time();

	va_start(ap, fmt);
	vsprintf(buf+strlen(buf), fmt, ap);
	strcat(buf, "\33[0m");
	
	if((strlen((char*)tcp_ascii_out) + strlen(buf)) < TCP_MAX_ASC_OUT_LEN)
		strcat((char*)tcp_ascii_out, buf);
	else
		strcpy((char*)tcp_ascii_out, buf);
	
	va_end(ap);

}


static int tcp_set_debug(u8 *log_flag, char *value)
{
	if(log_flag == NULL || value == NULL)
		return -1;
	if(strcmp(value, "on") == 0)
		*log_flag = TCP_LOG_ON;
	else if(strcmp(value, "off") == 0)
		*log_flag = TCP_LOG_OFF;
	else
		return 0;
	
	return 1;
}

static void tcp_set_all_debug()
{
	tcp_debug.log_debug = TCP_LOG_ON;
	tcp_debug.log_warn = TCP_LOG_ON;
	tcp_debug.log_err = TCP_LOG_ON;
	tcp_debug.log_func = TCP_LOG_ON;
}

int tcp_debug_init()
{
	u8	debug_status;
	u8	data[10];
	u8 	*ptr;
	char	version_info[16]={""};
	
	memset(tcp_ascii_in,0,128);
	memset(tcp_ascii_out,0,4096);
	sprintf(version_info,"V%d.%d.%02d",TCP_VERSION[0],TCP_VERSION[1],TCP_VERSION[2]);
//	memcpy(rtp_param.sys.version, TCP_VERSION, 4);
	
	ptr = data;
	debug_status = 1;
	debug_set_response(tcp_base_id_len, debug_status_id, &debug_status,1);
	debug_set_response(tcp_base_id_len, debug_name_id, (u8*)version_info,12);	/* module name */
	debug_set_response(tcp_base_id_len, debug_ascin_id, (u8*)tcp_ascii_in, 128);	/* ascii in buf */
	debug_set_response(tcp_base_id_len, debug_ascout_id, (u8*)tcp_ascii_out,4096);	/* ascii out buf */
	
	return 1;
}


static void tcp_command_decompose(char *opr, char *obj, char *value, char *cmd)
{
	int i;
	int len;
	char *sep;

	if(opr == NULL || obj == NULL || value == NULL || cmd == NULL)
		return ;
	opr[0] = obj[0] = value[0] = '\0';
	for(i = 0; i < 80; i++)
	{
		sep = strsep(&cmd, " \t");			/* Seprate by SPACE and TAB */
		if(sep == NULL)					/* Touch the end */
			return;
		else if((len = strlen(sep)) == 0)		/* Touch the SPACE or TAB */
			continue;
		if(opr[0] == '\0')
		{
			if(len < TCP_MAX_OPR_LEN)
				strcpy(opr, sep);
		}
		else if(obj[0] == '\0')
		{
			if(len < TCP_MAX_OBJ_LEN)
				strcpy(obj, sep);
		}
		else if(value[0] == '\0')
		{
			if(len < TCP_MAX_VALUE_LEN)
			{
				strcpy(value, sep);
				return;
			}
		}
	}
}

static int tcp_debug_cmd_handle(char *cmd)
{
	char opr[TCP_MAX_OPR_LEN] = {""};
	char obj[TCP_MAX_OBJ_LEN] = {""};
	char value[TCP_MAX_VALUE_LEN] = {""};
	char *ver = (char*)TCP_VERSION;
	char *str_start = NULL;
	int port;

	if(cmd == NULL)
		return -1;
	tcp_command_decompose(opr, obj, value, cmd);
	if(strcmp(opr, "help") == 0 || strcmp(opr, "?") == 0)
		tcp_print("%s\r\nV%d.%d.%02d T%03d\r\n", help_menu, ver[0], ver[1], ver[2], ver[3]);
	else if(strcmp(opr, "log") == 0)
	{
		if(strcmp(obj, "all") == 0)
			tcp_set_all_debug();
		else if(strcmp(obj, "none") == 0)
			memset(&tcp_debug, 0, sizeof(tcp_debug_t));
		else if(strcmp(obj, "debug") == 0)
			return tcp_set_debug(&tcp_debug.log_debug, value);
		else if(strcmp(obj, "warn") == 0)
			return tcp_set_debug(&tcp_debug.log_warn, value);
		else if(strcmp(obj, "error") == 0)
			return tcp_set_debug(&tcp_debug.log_err, value);
		else if(strcmp(obj, "func") == 0)
			return tcp_set_debug(&tcp_debug.log_func, value);
		else if(strcmp(obj, "time") == 0)
			return tcp_set_debug(&tcp_debug.log_time, value);
		else
			return 0;
	}
	else if(strcmp(opr, "list") == 0)
	{
		if(strstr(obj, "port") != NULL)
		{
			if((str_start = strstr(obj, "-")) != NULL)
			{
				port = strtol(str_start+1, NULL, 10);
				return tcp_print_port(port);
			}
			else
				return tcp_print_all_port();
		}
		else
			return 0;
	}
	else if (strcmp(opr, "reset") == 0)
	{
		if(strstr(obj, "stat") != NULL)
		{
			if((str_start = strstr(obj, "-")) != NULL)
			{
				port = strtol(str_start+1, NULL, 11);
				return tcp_clear_stat(port);
			}
			else
				return 0;
		}
		else
			return 0;
	}
/*	else if(strcmp(opr, "save") == 0)
	{
		if(strcmp(obj, "para") == 0)
			rtpproxy_param_save_para();
		else
			return 0;
	}
	else if(strcmp(opr, "load") == 0)
	{
		if(strcmp(obj, "para") == 0)
		{
			rtpproxy_modify_para();
		}
		else
			return 0;
	}*/
/*	else if(strcmp(opr, "save") == 0)
	{
		if(strcmp(obj, "rz") == 0)
			return rtp_save_rz();
		else if(strcmp(obj, "mg") == 0)
			return rtp_save_mg();
		else if(strcmp(obj, "sys") == 0)
			return rtp_save_system();
		else
			return 0;
	}
	else if(strcmp(opr, "test") == 0)
	{
		if(strcmp(obj, "port_enable") == 0)	//
		{
			int test_i;
			for(test_i = 1; test_i < 3; test_i++)
				test_rtp_set_port_enable(test_i);
		}
		else
			return 0;
	}*/
	else
		return 0;

	return 1;
}

void tcp_debug_timer()
{
	int	ret, len;
	char	cmd[128] = {""};
    
	if(tcp_ascii_in[0] == 0)
		return;
	len = strlen(tcp_ascii_in);
	if(len ==0)
		return;
	if(strlen((char*)&tcp_ascii_in[1]) >= 128)
		return;
	strcpy(cmd, (char*)&tcp_ascii_in[1]);
	memset(tcp_ascii_in, 0, TCP_MAX_ASC_IN_LEN);

	ret = tcp_debug_cmd_handle(cmd);
	if(ret == 1)
		tcp_print("Command OK!\r\n");
	else
		tcp_print("Command Error!\r\n");

}


