#include "./omcFuncLib.h"

static int readOmcdConf(void);
//----------from function.c-----------
/*
Convert data from ASCII form to right-aligned compact BCD form.
*/

void omc_AsciiToRbcd(unsigned char *bcd_buf, const char *ascii_buf,
					 int len)
{
	int i;
	char ch;

	if (len > 0)
		*bcd_buf = 0x00;
	for (i = 0; i < len; i++) {
		ch = ascii_buf[i];

		if ((ch >= '0') && (ch <= '9'))
			ch -= '0';
		else if ((ch >= 'A') && (ch <= 'F'))
			ch -= 'A' - 10;
		else if ((ch >= 'a') && (ch <= 'f'))
			ch -= 'a' - 10;
		else
			ch = 0;

		if ((len - i) & 1)
			*(bcd_buf++) |= ch & 0x0f;
		else
			*bcd_buf = ch << 4;
	}
}

/* 
Convert data from right-aligned compact BCD form to ASCII form.
*/
void omc_RbcdToAscii(char *ascii_buf, const unsigned char *bcd_buf,
					 int len)
{
	int i;
	char ch;
	//if(sizeof(*ascii_buf) < len*2){
	//  len = sizeof(*ascii_buf)/2;
	//}
	for (i = 0; i < len; i++) {
		if ((len - i) & 1) {
			ch = *(bcd_buf++) & 0x0f;
		} else {
			//ch = (*bcd_buf & 0xf0) >> 4;
			ch = *bcd_buf >> 4;
		}
		ascii_buf[i] = ch + ((ch > 9) ? 'A' - 10 : '0');
	}
	ascii_buf[i] = '\0';
}

//----------from snmp.c-----------
/*
BYTE encode_integer(BYTE *buf,DWORD val)
{
	if(val<128)
	{
		buf[0]=val;
		return 1;
	}
	else if(val<0x8000)
	{
		buf[0]=val >>8;
		buf[1]=val & 0xFF;
		return 2;
	}
	else if(val <0x800000)
	{
		buf[0]=val >>16;
		buf[1]=(val & 0xFF00)>>8;
		buf[2]=val & 0xFF;
		return 3;
	}
	else if(val <0x80000000)
	{
		buf[0]=val >>24;
		buf[1]=(val & 0xFF0000)>>16;
		buf[2]=(val & 0xFF00)>>8;
		buf[3]=val & 0xFF;
		return 4;
	}
	else
	{
		buf[0]=0;
		buf[1]=val >>24;
		buf[2]=(val & 0xFF0000)>>16;
		buf[3]=(val & 0xFF00)>>8;
		buf[4]=val & 0xFF;
		return 5;
	}
}

DWORD decode_integer(BYTE *buf,BYTE len)
{
	BYTE	i=0;
	DWORD	val=0;
	while(i<len)
		val=(val<<8)|buf[i++];
	return val;
}

*/

void clrscr(void)
{
	printf("\033[2J");			// Clear the entire screen.
	printf("\033[0;0f");		// Move cursor to the top left hand corner
}

/////////////////////////////////////////////////////////////////

int omcLogInit(const char *logFilePath, const char *logFileName,
			   FILE ** logFp)
{
	char logFile[128], cmdstr[64];
	long l_time;
	struct tm *t;
	l_time = time(NULL);
	t = localtime(&l_time);

	if (access(logFilePath, F_OK) != 0) {
		sprintf(cmdstr, "mkdir -p -m755 %s", logFilePath);
		system(cmdstr);
	}

	sprintf(logFile, "%s/%s_%02d_%02d.log", logFilePath, logFileName,
			t->tm_mon + 1, t->tm_mday);
	
	if(*logFp != NULL)
		fclose(*logFp);
		
	*logFp = fopen(logFile, "a");
	if (*logFp == NULL) {
		perror("Can't Create log file\n");
		return (-1);
	}
	omcLog(*logFp, "===================Start====================");
	return (0);
}

void omcLog(FILE * logFp, const char *fmt, ...)
{
	char buf[8196];
	char logDate[30];
	va_list args;
	long l_time;
	struct tm *t;
	l_time = time(NULL);

	t = localtime(&l_time);
	sprintf(logDate, "\n%02d-%02d %02d:%02d:%02d \t", t->tm_mon + 1,
			t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
	//strftime(logDate,sizeof(logDate),"\n%m-%d %H:%M:%S \t",t);
	if (logFp == NULL) {
		return;
	}
	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	fputs(logDate, logFp);
	fputs(buf, logFp);
	fflush(logFp);
	va_end(args);
}

void StringCut(char *str, int c)
{
	if (toupper(*str) == toupper(c))
		*str = 0;
	while (str && *str++)
		if (toupper(*str) == toupper(c)) {
			*str = 0;
			break;
		}
}

void ems_debug(char *file,const char *fmt,...)
{
	char logFile[64];
	FILE *fp;
	time_t l_time;
	va_list ap;
	char buf[8192];
	struct tm *t;
	char timestr[64];
	
	l_time=time(NULL);
	t=localtime(&l_time);
	sprintf(logFile,"/usr/local/omc/log/%s%04d%02d%02d.log",file,t->tm_year+1900,t->tm_mon+1,t->tm_mday);
	fp=fopen(logFile,"a");
	if(fp!=NULL)
	{
		va_start(ap,fmt);
		vsprintf(buf,fmt,ap);
		sprintf(timestr,"%02d:%02d:%02d: ",t->tm_hour,t->tm_min,t->tm_sec);
		fputs(timestr,fp);
		fputs(buf,fp);
		fputs("\n",fp);
		fflush(fp);
		va_end(ap);
		fclose(fp);
	}
}

static struct timeval ltv1, ltv2;
static struct timezone ltz;
static char ltime_mark_name[64];
	
void time_mark_start(char *desc)
{
	sprintf(ltime_mark_name,"%s",desc);
	gettimeofday(&ltv1, &ltz);
}

unsigned long time_mark_end()
{
	unsigned long elapse;
	gettimeofday(&ltv2, &ltz);
	elapse=(ltv2.tv_sec - ltv1.tv_sec) * (1000000) + ltv2.tv_usec - ltv1.tv_usec;
	ems_debug("/tmp/time.log","%s consume time %ld microseconds\r\n",ltime_mark_name,elapse);
	return elapse;
}





/*
Register the sync source data
Parameter: provide the source data name
return: the id of this source data setting
*/
static _sync_source sync_source[64];
static int sync_source_count=0;
static int sync_enable=0;
int sync_data_register(char *name)
{
	FILE *handle;
	char line[2048],*part;
	char filename[256];
	int len,i,index,ret;

	
	// initial
	if(sync_source_count == 0)
	{
		readOmcdConf();
		if(sync_enable)
			printf("Sync data function on\n");
		else
			printf("Sync data function off\n");
		
		handle=fopen("./dual/sync_source.conf","r");
		if(!handle)
		{
			printf("Can not find sync_source.conf file\n");
			exit(1);
		}
		
		while(fgets(line,2048,handle))
		{
			len=strlen(line);
			if(len < 8)
				continue;
			for(i=0;i<len;i++)
			{
				if(!isspace(line[i]))
					break;
			}
			if(line[i] == '#')
				continue;
			
			// name
			part=strtok(line,",");
			if(!part)
			{
				printf("Error format in sync_source.conf\n");
				exit(1);
			}
			sprintf(sync_source[sync_source_count].name,"%s",part);
			// IO_PROC_SCRIPT
			part=strtok(NULL,",");
			if(!part)
			{
				printf("Error format in sync_source.conf\n");
				exit(1);
			}
			// DATA_PROC_SCRIPT
			part=strtok(NULL,",");
			if(!part)
			{
				printf("Error format in sync_source.conf\n");
				exit(1);
			}
			// SYNC_FILE_SIZE
			part=strtok(NULL,",");
			if(!part)
			{
				printf("Error format in sync_source.conf\n");
				exit(1);
			}
			sync_source[sync_source_count].syncfilesize=atoi(part);
			// SEND_DIR
			part=strtok(NULL,",");
			if(!part)
			{
				printf("Error format in sync_source.conf\n");
				exit(1);
			}
			sprintf(sync_source[sync_source_count].senddir,"%s",part);
			sync_source_count++;
		}
		fclose(handle);
		
		if(sync_source_count == 0)
		{
			printf("You haven't configure the sync_source\n");
			exit(1);
		}
	}
	
	// find the sync data source
	for(i=0;i<sync_source_count;i++)
	{
		if(strcmp(sync_source[i].name,name) == 0)
		{
			index=i;
			break;
		}
	}
	if(i == sync_source_count)
	{
		printf("Can not find the sync_source %s\n",name);
		exit(1);
	}
	
	// get the sync_file_index
	sprintf(filename,"%s/file.index",sync_source[index].senddir);
	handle=fopen(filename,"r");
	if(!handle)
	{
		sync_source[index].syncfileindex=0;
	}
	else
	{
		ret=fread(&sync_source[index].syncfileindex,sizeof(sync_source[index].syncfileindex),1,handle);
		if(1 != ret)
		{
			ems_debug("write_sync_data","Can not read the index from %s, set to 1,ret=%d",filename,ret);
			sync_source[index].syncfileindex=0;
		}
		else
		{
			sync_source[index].syncfileindex++;
			sync_source[index].syncfileindex%=MAX_SYNC_FILE_INDEX;
		}
	}
	
	handle=fopen(filename,"w");
	if(!handle)
	{
		ems_debug("write_sync_data","Fail to open %s",filename);
		exit(1);
	}
	fwrite(&sync_source[index].syncfileindex,sizeof(sync_source[index].syncfileindex),1,handle);
	fclose(handle);
	
	sync_source[index].curfilesize=0;
	sprintf(sync_source[index].curfilename,"%s/%06d.dat",sync_source[index].senddir,sync_source[index].syncfileindex);
	
	return index;
}

/*
Write the data into sync file	
*/
char syncdata[8192*2];
int sync_data_write(int id, char *data, int datalen)
{
	FILE *handle;
	char filename[256];
	
	if(!sync_enable)
		return 1;
	if(sync_source[id].curfilesize > sync_source[id].syncfilesize)
	{
		
		sprintf(filename,"%s/%06d.end",sync_source[id].senddir,sync_source[id].syncfileindex);
		handle=fopen(filename,"w");
		if(!handle)
		{
			ems_debug("write_sync_data","Fail to open %s",filename);
			exit(1);
		}
		fclose(handle);
		
		sync_source[id].syncfileindex++;
		sync_source[id].syncfileindex%=MAX_SYNC_FILE_INDEX;
		sync_source[id].curfilesize=0;
		sprintf(sync_source[id].curfilename,"%s/%06d.dat",sync_source[id].senddir,sync_source[id].syncfileindex);
		
		sprintf(filename,"%s/file.index",sync_source[id].senddir);
		handle=fopen(filename,"w");
		if(!handle)
		{
			ems_debug("write_sync_data","Fail to open %s",filename);
			exit(1);
		}
		fwrite(&sync_source[id].syncfileindex,sizeof(sync_source[id].syncfileindex),1,handle);
		fclose(handle);
		
		ems_debug("write_sync_data","Prepare to write file %06d",sync_source[id].syncfileindex);
	}
	handle=fopen(sync_source[id].curfilename,"a");
	sprintf(syncdata,"%s\n",data);
	fwrite(syncdata,datalen+1,1,handle);
	sync_source[id].curfilesize+=datalen+5;
	fclose(handle);
	return 1;
}

/*
read the omcd.conf
*/
static int readOmcdConf(void)
{
	char fileName[512];
	unsigned char buf[4096];
	unsigned char param[32][512];
	char paramName[128];
	char paramValue[384];
	char* temp;
	FILE* fp;
	int fi;
	int i;
	//int j;
	int paramCount;
	int byteCount;
	
	paramCount=0;
	byteCount=0;
	memset(buf,0,4096);
	memset(param,0,32*512);
	sprintf(fileName,"./conf/omcd.conf");
	fp=fopen(fileName,"r");
	if(fp)
	{		
		fi=fileno(fp);
		if(read(fi,buf,4096))
		{
			for(i=0;i<4096;i++)
			{
				
				if(buf[i] == 0x0A)
				{
					//printf("\n");
					if(byteCount<512 && param[paramCount][0] != 0x00 && param[paramCount][0] != 0x23)
						paramCount++;
					else
						memset(param[paramCount],0,512);	
					byteCount=0;
				}	
				else
				{	
					param[paramCount][byteCount]=buf[i];
					byteCount++;
				}				
			}
			
			for(i=0;i<paramCount;i++)
			{
				temp=strtok((char*)param[i],"=");
				sprintf(paramName,"%s",temp);
				//printf("Name=%s,",temp);
				temp=strtok(NULL,"=");
				sprintf(paramValue,"%s",temp);
				//printf("Value=%s\n",temp);

				if(strcasecmp(paramName,"omcRunMode") == 0)
				{
					sync_enable=atoi(paramValue);
				}	
			}
		}
		close(fi);
		fclose(fp);
	}	
	else
	{
		printf("The omcd.conf does not exist!\n");
		exit(1);
	}		
	
	return 1;
}
