#include "./include/mgc_debug.h"
#include "./include/mgc_mg_info.h"
#include "./include/mgc_phy_port.h"
#include "./include/mgc_chnl_info.h"
#include "./include/mgc_port_info.h"
#include "../../debug/src/include/debug.h"

#define MGC_DEBUG_ID	18
#define	MGC_VER_DEBUG	"R9V0_07"

static char ascii[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
						 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};

static BYTE	log_help[] = {
"MGC Debug Monitor Help:\n\r\
\n\r\
1.[help]                                    display help menu\n\r\
2.[log info on/off]                         display info logs\n\r\
3.[log error on/off]                        display error logs \n\r\
4.[log warn on/off]                         display warn logs \n\r\
5.[log all/none]                            display all/none logs\n\r\
6.[log record -f FILENAME]                  write debug message to FILENAME \n\r\
7.[print mg ID/Domain]                      print mg[ID]/Domain info \n\r\
"
};

static	WORD	disp_page[10];
static	BYTE	*disp_ptr = (BYTE *) disp_page;

static 	DWORD	debug_status_id[20] = 
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,MGC_DEBUG_ID + 2,1
	};
	
static	BYTE 	debug_status = 1;

static DWORD	debug_name_id[20] = 
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,MGC_DEBUG_ID + 2,2
	};
	
static DWORD	debug_ascin_id[20] = 
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,MGC_DEBUG_ID + 2,3
	};

static DWORD	debug_ascout_id[20] = 
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,MGC_DEBUG_ID + 2,4
	};
		
static	DWORD	debug_page_title[20] = 		
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,MGC_DEBUG_ID + 2,1,1
	};
	
static	DWORD	debug_page_line[20] = 		
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,MGC_DEBUG_ID + 2,1,2,1
	};
		
const static BYTE	MGC_BASE_ID_LEN = 15;
const static BYTE	MGC_PAGE_POINT 	= 14;
const static BYTE  	MGC_LINE_POINT 	= 15;

static BYTE	title1_p[] = 
{
	"    MGC    Page 01    MG Info\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Subpage\n\r\
MG_Info\n\r"
};

static BYTE	title2_p[] = 
{
	"    MGC    Page 02    Phy Port Info\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Subpage\n\r\
Phy_Port\n\r"
};

static BYTE	title3_p[] = 
{
	"    MGC    Page 03    Channel Info\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Subpage\n\r\
Chnl_Info\n\r"
};

static BYTE	title4_p[] = 
{
	"    MGC    Page 04    Port Info\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Port_Info\n\r"
};

#define FILENAMELEN 128
static char fileName[FILENAMELEN];

BYTE mgc_disp_line(BYTE page, BYTE line)
{
	BYTE	disp_length;
	
	disp_length = 16;
	disp_ptr 	= (BYTE *) disp_page;
	
	switch (page)
	{
		case 1:	// Page 1: MG Info
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else
				disp_ptr 	= (BYTE *) mgc_mg_info_get_res_addr() + disp_page[page] * sizeof(MG_INFO) + (line - 1) * 16;
			break;
		case 2:	// Page 2: Phy Port Info
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else
				disp_ptr 	= (BYTE *) mgc_phy_port_get_res_addr() + disp_page[page] * sizeof(PHY_PORT_INFO) + (line - 1) * 16;
			break;
		case 3:	// Page 3: Channel Info
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else
				disp_ptr 	= (BYTE *) mgc_chnl_info_get_res_addr + disp_page[page] * sizeof(CHNL_INFO) + (line - 1) * 16;
			break;
		case 4:	// Page 4: Software Port Info
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else
				disp_ptr 	= (BYTE *) mgc_port_info_get_res_addr + disp_page[page] * sizeof(PORT_INFO) + (line - 1) * 16;
			break;
		default:
			disp_length = 0;
			break;
	}

	return disp_length;
}

void mgc_disp_page(BYTE page)
{
	BYTE	disp_line;
	BYTE	disp_length;

	debug_page_line[MGC_PAGE_POINT] = page + 5;
	
	for (disp_line = 0; disp_line < 22; disp_line++)
	{
		disp_length = mgc_disp_line(page, disp_line);
		debug_page_line[MGC_LINE_POINT] = disp_line + 2;
		debug_page_line[MGC_LINE_POINT + 1] = 2;	// Data Pointer
		debug_set_response(MGC_BASE_ID_LEN + 2, debug_page_line, disp_ptr, disp_length);
	}
}

int	mgc_debug_set(void)
{
	BYTE	page;
	BYTE	data[10];
	BYTE 	*ptr;
	time_t timep;
	struct tm *p;	
	bzero(disp_page, 20);
	
	ptr = data;
	
	debug_set_response(MGC_BASE_ID_LEN, debug_status_id, &debug_status, 1);
	debug_set_response(MGC_BASE_ID_LEN, debug_name_id, MGC_VER_DEBUG, 10);
	debug_set_response(MGC_BASE_ID_LEN, debug_ascin_id, mgcAsciInBuf, 4096);
	debug_set_response(MGC_BASE_ID_LEN, debug_ascout_id, mgcAsciOutBuf, MGC_MAX_ASCIIOUT_LEN);
	
	for (page = 1; page < 5; page++)
	{
		switch (page)
		{
			case 1: //page 1
				ptr = title1_p;
				break;
			case 2: //page 2
				ptr = title2_p;
				break;
			case 3: //page 3
				ptr = title3_p;
				break;
			case 4: //page 4
				ptr = title4_p;
				break;
			default:
				break;				
		}
		
		debug_page_title[MGC_PAGE_POINT] = 5 + page;
		debug_set_response(MGC_BASE_ID_LEN + 1, debug_page_title, ptr, strlen(ptr));
		mgc_disp_page(page);
	}

//	mkdir("mgc_log" , 777);
    time(&timep);
	p = gmtime(&timep);
	
    memset(fileName , 0 , FILENAMELEN);
	//sprintf(fileName , "mgc_log/mgc_log_%d_%d_%d_%d.txt", p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);	
	return 1;
}


BOOL mgc_debug_parse_print_info(char *pAscin)
{
    char *ptr = NULL;
	char *ptrTmp = NULL;
	MG_INFO *pMgInfo = NULL;
	int id = -1;
	
    if(pAscin == NULL)
        return FALSE;

    if(strstr(pAscin , "print") == NULL)
	    return FALSE;
    
    ptr = strstr(pAscin , "mg");
    if(ptr == NULL)
	    return FALSE;

	ptr = ptr+2;
	
	while(*ptr != '\n')
	{
	    if(*ptr != ' ')
	    {
	        ptrTmp = ptr;
			break;
	    }

		ptr++;
	}

    if(ptrTmp == NULL)
	    return FALSE;

    pMgInfo = mgc_mg_info_find_mg_by_name(ptrTmp);
	if(pMgInfo == NULL)
	{
	id = atoi(ptrTmp);
	pMgInfo = mgc_mg_info_get_index_mg(id);
	}

	if(pMgInfo == NULL)
	    return FALSE;

	mgc_mg_info_print_info(pMgInfo);
	return TRUE;
}


BOOL mgc_debug_parse_log_file(char *pAscin)
{
    char *ptr = NULL;
	char *ptrTmp = NULL;
	int i=0;
    FILE *fp;
	
    if(pAscin == NULL)
        return FALSE;

    if(strstr(pAscin , "log record") == NULL)
	    return FALSE;

    ptr = strstr(pAscin , "-f");
    if(ptr == NULL)	
	    return FALSE;

    memset(fileName , 0 , FILENAMELEN);
    ptr = ptr+2;
    while(*ptr != '\n')
    {
        if(*ptr != ' ')
        {
            ptrTmp = ptr;
			break;
        }

		ptr++;
    }

    if(ptrTmp == NULL)
	    return FALSE;

    while(*ptr != '\0')
    {
        ptr++;
		i++;
		if(i>=FILENAMELEN)
		   break;	
    }

    if(i>=FILENAMELEN)
	    return FALSE;	

    memcpy(fileName, ptrTmp , ptr-ptrTmp);
   
    fp = fopen(fileName , "w+");    	
	if(fp == NULL)
	    return FALSE;

    fclose(fp);
	return TRUE;
}


BOOL mgc_debug_write_file(char *msg , int len)
{
    FILE *fp = NULL;

    if(strlen(fileName) == 0)
	    return FALSE;

    fp = fopen(fileName , "a");  	
    if(fp == NULL)
	    return FALSE;

    if(fwrite(msg, sizeof(char) , len , fp) < len)
	    return FALSE;

    fclose(fp);
	return TRUE;
}

int	mgc_asciout_proc(BYTE *out_str)
{
	int out_len;
	
	out_len = strlen(out_str);
		
	if (out_len + strlen(mgcAsciOutBuf) > MGC_MAX_ASCIIOUT_LEN - 2)
	{
		strcpy(mgcAsciOutBuf, out_str);
	}
	else
		strcat(mgcAsciOutBuf, out_str);
	
	return 1;
}

void mgc_log_all()
{
	WORD	i;
	
	for (i = 0; i < MGC_MAX_NUM_OF_MG; i++)        
	    mgc_mg_info_set_mon(i , TRUE);
	
	for (i = 0; i < MGC_MAX_NUM_OF_PHY_PORT; i++)
        mgc_phy_port_set_mon(i, TRUE);
	
	for (i = 0; i < MGC_MAX_NUM_OF_CHNL; i++)
        mgc_chnl_info_set_mon(i, TRUE);
}

void mgc_log_none()
{
	WORD	i;
	
	for (i = 0; i < MGC_MAX_NUM_OF_MG; i++)
	    mgc_mg_info_set_mon(i , FALSE);

	
	for (i = 0; i < MGC_MAX_NUM_OF_PHY_PORT; i++)
        mgc_phy_port_set_mon(i, FALSE);

	
	for (i = 0; i < MGC_MAX_NUM_OF_CHNL; i++)
        mgc_chnl_info_set_mon(i, FALSE);

    memset(fileName , 0 , FILENAMELEN);
}

void mgc_mon(void)
{
	BYTE	in_page, err_fg = 0;
	BYTE	*ascii_in_ptr 	= NULL;
	BYTE	*str_start 		= NULL;
	WORD	str_len;
	WORD	num;
//	WORD mgNo, chlNo , portNo;
	//PHY_PORT_INFO *pPhyPort;
	//CHNL_INFO *pChnlInfo;
	
	if ((str_len = strlen(mgcAsciInBuf)) > 0)
	{
		in_page = mgcAsciInBuf[0] - 1;
		ascii_in_ptr = mgcAsciInBuf + 1;
		
		if (in_page > 4)
			err_fg = 1;
		else if (strcmp(ascii_in_ptr,"log error on") == 0)
		{
			mgcMonitorFg = mgcMonitorFg | MGC_MONITOR_ERROR;
		}
		else if (strcmp(ascii_in_ptr,"log error off") == 0)
		{
			mgcMonitorFg = mgcMonitorFg & (~MGC_MONITOR_ERROR);			
		}
		else if (strcmp(ascii_in_ptr,"log warn on") == 0)
		{
			mgcMonitorFg = mgcMonitorFg | MGC_MONITOR_WARN;
		}
		else if (strcmp(ascii_in_ptr,"log warn off") == 0)
		{
			mgcMonitorFg = mgcMonitorFg & (~MGC_MONITOR_WARN);			
		}		
		else if (strcmp(ascii_in_ptr,"log info on") == 0)
		{
			mgcMonitorFg = mgcMonitorFg | MGC_MONITOR_INFO;
		}		
		else if (strcmp(ascii_in_ptr,"log info off") == 0)
		{
			mgcMonitorFg = mgcMonitorFg & (~MGC_MONITOR_INFO);			
		}			
		else if (strcmp(ascii_in_ptr,"log all") == 0)
		{
			mgcMonitorFg = MGC_MONITOR_ALL;
			mgc_log_all();
		}
		else if (strcmp(ascii_in_ptr,"log none") == 0)
		{
			mgcMonitorFg = MGC_MONITOR_NONE;
			mgc_log_none();
		}
		else if (strcmp(ascii_in_ptr,"help") == 0)
		{
			mgc_asciout_proc(log_help);
		}
		else if(strstr(ascii_in_ptr, "log record") != NULL)
		{
		    if(mgc_debug_parse_log_file(ascii_in_ptr) == FALSE)
			    err_fg = 1;
		}
		else if(strstr(ascii_in_ptr, "print") != NULL)
		{
		    if(mgc_debug_parse_print_info(ascii_in_ptr) == FALSE)
			    err_fg = 1;	
		}
#if 0		
		else if (strstr(ascii_in_ptr, "log mg") != NULL)
		{
			if ((str_start = strstr(ascii_in_ptr, "-")) != NULL)
			{
				mgNo = strtoul(str_start + 1, NULL, 10);
				if (mgNo >= MGC_MAX_NUM_OF_MG)
					err_fg = 1;
				else if (strstr(ascii_in_ptr, "on") != NULL)
					mgcMgInfo[mgNo].monFlag = 1;
				else if (strstr(ascii_in_ptr, "off") != NULL)
					mgcMgInfo[mgNo].monFlag = 0;
				else
					err_fg = 1;
			}
			else
				err_fg = 1;
		}
		else if (strstr(ascii_in_ptr, "log port") != NULL)
		{
			if ((str_start = strstr(ascii_in_ptr, "-")) != NULL)
			{
				mgNo = strtoul(str_start + 1, NULL, 10);
				if (mgNo >= MGC_MAX_NUM_OF_MG)
					err_fg = 1;
				if ((str_start = strstr(str_start + 1, "-")) != NULL)
				{
					portNo = strtoul(str_start + 1, NULL, 10);
					if (portNo >= MGC_MAX_PHY_PORT_PER_MG)
						err_fg = 1;
					pPhyPort = mgc_phy_port_find_port_of_mg(&(mgcMgInfo[mgNo]), portNo);
					if (pPhyPort == NULL)
						err_fg = 2;
					else
					{
						if (strstr(str_start + 1, "on") != NULL)
							pPhyPort->monFlag = 1;
						else if (strstr(ascii_in_ptr, "off") != NULL)
							pPhyPort->monFlag = 0;
						else
							err_fg = 1;
					}
				}
			}
			else
				err_fg = 1;
		}
		else if (strstr(ascii_in_ptr, "log chnl") != NULL)
		{
			if ((str_start = strstr(ascii_in_ptr, "-")) != NULL)
			{
				mgNo = strtoul(str_start + 1, NULL, 10);
				if (mgNo >= MGC_MAX_NUM_OF_MG)
					err_fg = 1;
				if ((str_start = strstr(str_start + 1, "-")) != NULL)
				{
					portNo = strtoul(str_start + 1, NULL, 10);
					if (portNo >= MGC_MAX_PHY_PORT_PER_MG)
						err_fg = 1;
					pPhyPort = mgc_phy_port_find_port_of_mg(&mgcMgInfo[mgNo], portNo);
					if (pPhyPort == NULL)
						err_fg = 2;
					else
					{
						if ((str_start = strstr(str_start + 1, "-")) != NULL)
						{
							chlNo = strtoul(str_start + 1, NULL, 10);
							pChnlInfo = mgc_chnl_info_find_chnl_of_phy(pPhyPort, chlNo);
							if (strstr(str_start + 1, "on") != NULL)
								pChnlInfo->monFlag = 1;
							else if (strstr(ascii_in_ptr, "off") != NULL)
								pChnlInfo->monFlag = 0;
							else
								err_fg = 1;
						}
					}
				}
			}
			else
				err_fg = 1;
		}
#endif		
		else if (isdigit(ascii_in_ptr[0]))
		{
			num = strtoul(ascii_in_ptr, NULL, 10);
			disp_page[in_page] = num;
			mgc_disp_page(in_page);
		}
		else if ((str_start = strstr(ascii_in_ptr, ">")) != NULL)
		{
			num = strtoul(str_start + 1, NULL, 10);
			disp_page[in_page] += num;
			mgc_disp_page(in_page);
		}
		else if ((str_start = strstr(ascii_in_ptr, "<"))!= NULL)
		{
			num = strtoul(str_start + 1, NULL, 10);
			disp_page[in_page] -= num;
			mgc_disp_page(in_page);
		}
		else
			err_fg = 1;
		
		if (err_fg == 0)
			mgc_asciout_proc("Command OK!\n\r");
		else if (err_fg == 2)
			mgc_asciout_proc("MG port not created!\n\r");
		else
			mgc_asciout_proc("Command Error!\n\r");
		
		strcpy(mgcAsciInBuf, "\0");
	}
}

int	mgc_hex_to_ascii(BYTE *from_hex, BYTE from_len, BYTE *to_asc)
{
	int	i, j;
	
	j = 0;
	
	for (i = 0; i< from_len; i++)
	{
		to_asc[j] = ascii[from_hex[i] >> 4];
		j++;
		to_asc[j] = ascii[from_hex[i] & 0x0F];
		j++;
		to_asc[j] = ' ';
		j++;
	}
	
	to_asc[j] = '\0';
	
	return 1;
}

int mgc_log_err(char *err_msg)
{
	if ((mgcMonitorFg & MGC_MONITOR_ERROR) == MGC_MONITOR_ERROR)
	{
		mgc_asciout_proc("\33[31m");
		if (strlen(err_msg) >= MGC_MAX_ASCITMP_LEN)
			sprintf(mgcAsciTempBuf, "log msg is too long!\n\r");
		else
			sprintf(mgcAsciTempBuf, "%s", err_msg);
		strcat(mgcAsciTempBuf, "\33[37m");
		mgc_asciout_proc(mgcAsciTempBuf);
	}
	
	return 1;
}

int mgc_log_warn(char *err_msg)
{
	if ((mgcMonitorFg & MGC_MONITOR_WARN) == MGC_MONITOR_WARN)
	{
		mgc_asciout_proc("\33[33m");
		if (strlen(err_msg) >= MGC_MAX_ASCITMP_LEN)
			sprintf(mgcAsciTempBuf, "log msg is too long!\n\r");
		else
			sprintf(mgcAsciTempBuf, "%s", err_msg);
		strcat(mgcAsciTempBuf, "\33[37m");
		mgc_asciout_proc(mgcAsciTempBuf);
	}
	
	return 1;
}


int mgc_log_info(char *err_msg)
{
	if ((mgcMonitorFg & MGC_MONITOR_INFO) == MGC_MONITOR_INFO)
	{
		mgc_asciout_proc("\33[32m");
		if (strlen(err_msg) >= MGC_MAX_ASCITMP_LEN)
			sprintf(mgcAsciTempBuf, "log msg is too long!\n\r");
		else
			sprintf(mgcAsciTempBuf, "%s", err_msg);
		strcat(mgcAsciTempBuf, "\33[37m");
		mgc_asciout_proc(mgcAsciTempBuf);
	}
	
	return 1;
}


int mgc_log_procedure(WORD mgNo, WORD portIndex, WORD chnlIndex, char *msg)
{
/*
	BYTE	monFlag = 0;
	
	if ((mgNo < MGC_MAX_NUM_OF_MG) && (mgcMgInfo[mgNo].monFlag == 1))
		monFlag = 1;
	else if ((portIndex < MGC_MAX_NUM_OF_PHY_PORT) && (mgcPhyPort[portIndex].monFlag == 1))
		monFlag = 1;
	else if ((chnlIndex < MGC_MAX_NUM_OF_CHNL) && (mgcChnl[chnlIndex].monFlag == 1))
		monFlag = 1;
	
	if (monFlag == 1)
	{
		if (strlen(msg) >= MGC_MAX_ASCITMP_LEN)
			sprintf(mgcAsciTempBuf, "log msg is too long!\n\r");
		else
			sprintf(mgcAsciTempBuf, "%s\n\r", msg);
		mgc_asciout_proc(mgcAsciTempBuf);
		return 0;
	}
*/	
	return -1;
}

#ifndef MGC_TEST_DEBUG
void MGC_DEBUG(char *msg,...)
{
    char printedMessage[MGC_MAX_LINE_LENGTH];
    char* ptr;
    va_list v;

    ptr = printedMessage;
    memset(ptr , 0 , MGC_MAX_LINE_LENGTH);

    sprintf(ptr, "DEBUG:");	
	ptr = ptr+strlen(ptr);
    /* Format the given line with the arguments */
    va_start(v, msg);
    vsprintf(ptr, msg, v);
    va_end(v);

	ptr = ptr+strlen(ptr);
    sprintf(ptr, "\r\n");
    ptr = printedMessage;

    if((mgcMonitorFg&MGC_MONITOR_DEBUG) != MGC_MONITOR_DEBUG)
	    return;	
	
    mgc_debug_write_file(ptr, strlen(ptr));	
    mgc_asciout_proc(ptr);
	return;
}

void MGC_WARN(char *msg,...)
{
    char printedMessage[MGC_MAX_LINE_LENGTH];
    char* ptr;
    va_list v;

    ptr = printedMessage;
    memset(ptr , 0 , MGC_MAX_LINE_LENGTH);
    sprintf(ptr, "WARN:");	
	ptr = ptr+strlen(ptr);
	
    /* Format the given line with the arguments */
    va_start(v, msg);
    vsprintf(ptr, msg, v);
    va_end(v);

	ptr = ptr+strlen(ptr);
    sprintf(ptr, "\r\n");
    ptr = printedMessage;	

    if((mgcMonitorFg&MGC_MONITOR_WARN) != MGC_MONITOR_WARN)
	  return; 

    mgc_debug_write_file(ptr, strlen(ptr));  
    mgc_log_warn(ptr);
	return;
}


void MGC_INFO(char *msg,...)
{
    char printedMessage[MGC_MAX_LINE_LENGTH];
    char* ptr;
    va_list v;

    ptr = printedMessage;
    memset(ptr , 0 , MGC_MAX_LINE_LENGTH);
    sprintf(ptr, "INFO:");	
	ptr = ptr+strlen(ptr);
	
    /* Format the given line with the arguments */
    va_start(v, msg);
    vsprintf(ptr, msg, v);
    va_end(v);

	ptr = ptr+strlen(ptr);
    sprintf(ptr, "\r\n");
    ptr = printedMessage;	
	
    if((mgcMonitorFg&MGC_MONITOR_INFO) != MGC_MONITOR_INFO)
	  return; 
  
    mgc_debug_write_file(ptr, strlen(ptr));    
    mgc_log_info(ptr);
	return;
}


void MGC_ERROR(char *msg,...)
{
    char printedMessage[MGC_MAX_LINE_LENGTH];
    char* ptr;
    va_list v;

    ptr = printedMessage;
    memset(ptr , 0 , MGC_MAX_LINE_LENGTH);

    sprintf(ptr, "ERROR:");	
	ptr = ptr+strlen(ptr);	
    /* Format the given line with the arguments */
    va_start(v, msg);
    vsprintf(ptr, msg, v);
    va_end(v);

  	ptr = ptr+strlen(ptr);
    sprintf(ptr, "\r\n");
    ptr = printedMessage;	

    if((mgcMonitorFg&MGC_MONITOR_ERROR) != MGC_MONITOR_ERROR)
	    return;		
	
    mgc_debug_write_file(ptr, strlen(ptr));	
    mgc_log_err(ptr);
	return;
}
#endif
