#include "Windows.h"
#include "RecordClass.h"
#include <stdarg.h>
#include "CommonTypes.h"
#include "CommonQueue.h"
#include <shellapi.h>
#include "malloc.h"
#include "stdlib.h"

FILE * openlogfile(CHAR *dirName);
INT32 WriteData(LPVOID pParam);
void WinRardirByhour( CHAR *dirName );
extern UINT8 qjLogSaveTime;

RecordLogClass::RecordLogClass(UINT8 recodFlag,CHAR *folderName)
{	
	filecounter = 0;
	fp = NULL;
	logFlg = 0;
	if(recodFlag != 0)
	{
		if (!CreateDirectoryA(".\\PrtclLog", NULL)) 
		{ 
			/* 不成功说明该目录存在,因此不需要创建 */
		} 
		else
		{
			/* */
		}

		logFlg = 1;
		if(folderName != NULL)
		{
			sprintf(dirName,".\\PrtclLog\\%s",folderName);
		}
		else
		{
			sprintf(dirName,"%s",".\\PrtclLog");
		}
		_log_buff = (CHAR*)malloc(sizeof(CHAR)*1024*100);
		fp = openlogfile(dirName);
        _pwriteque = (QueueStruct *)malloc(sizeof(QueueStruct));		
		QueueInitial(_pwriteque,1024*1024);
	    _dwWriteThread = NULL;
		hWritedataSemaphore = CreateSemaphore(NULL,1,1,NULL);				
	}
}
RecordLogClass::~RecordLogClass()
{
	if(logFlg != 0)
	{
		Release();
	}
	if(fp != NULL)
	{
		fclose(fp);
	}
}
UINT8 RecordLogClass::Release()
{
	logFlg = 0;
	if(_dwWriteThread != NULL)	/* 如果线程启动，则关闭*/
	{
		TerminateThread(_hWriteThread,_dwWriteThread);
		_dwWriteThread =0;
	}

	if(_pwriteque != NULL)
	{
		QueueElementFree(_pwriteque);
		free(_pwriteque);
		_pwriteque = NULL;
	}

	if(fp != NULL)
	{
		fclose(fp);
		fp = NULL;
	}

	return 1;
}

/*
 * 开启进程
 */
UINT8  RecordLogClass::StartWrite()
{
	_hWriteThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WriteData,(LPVOID)this,0,&_dwWriteThread);
	SetThreadPriority(_hWriteThread,THREAD_PRIORITY_BELOW_NORMAL);
	return 1;
}
	
UINT8 RecordLogClass::Log(CHAR* fmt,...)
{
	va_list para;
	UINT8  ret= 0;
	UINT32 len = 0;
	if(logFlg == 0)
	{
		return 1;
	}
	if(_dwWriteThread == NULL)
	{
		StartWrite();
	}
	else
	{
	}

	if(fp == NULL)
	{
		return 1;
	}

	va_start(para,fmt);
	len = vsprintf(_log_buff,fmt,para);
	
    /*加锁*/
#if 1
	WaitForSingleObject(hWritedataSemaphore,INFINITE);
	
	if(len >0)
	{
		ret = QueueWrite(len,(UINT8 *)_log_buff,_pwriteque);/*将数组中的数据写入队列*/
	}

    /* 解锁 */
	ReleaseSemaphore(hWritedataSemaphore,1,NULL);
#else
	if(len>0)
	{
		fwrite(_log_buff,len,1,fp);
		fflush(fp);
		filecounter +=len;
		if(filecounter > 1024*1024*20)
		{
			fclose(fp);
			filecounter = 0;
			fp = openlogfile(dirName);
		}
	}
#endif
	return 1;
}


/*删除指定的文件*/
void DeldirByday( CHAR *dirName )
{
	time_t CurSeconds;   /*时间变量*/
	time_t PreSeconds;  /*时间变量*/
	struct tm *dellocaltime=NULL;  /*时间变量*/
	CHAR fileName[400]; /*目录变量*/
	CHAR rarfileName[400]; /*目录变量*/
	char DelCmd1[400]={0}; /*临时变量*/
	char DelCmd2[400]={0};  /*临时变量*/
	int i; /*循环变量*/
	int ret=0;
	int ret1=0;
	WCHAR szDest[800];
	memset(szDest, '\0', sizeof(WCHAR) * 800);
	memset(fileName,'\0',sizeof(CHAR) * 400); /*初始化变量*/
	memset(rarfileName,'\0',sizeof(CHAR) * 400); /*初始化变量*/
	time(&CurSeconds);   /*获取本地时间*/
	SHELLEXECUTEINFO ShExecInfo = { 0 };
	ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
	ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
	ShExecInfo.hwnd = NULL;
	ShExecInfo.lpVerb = NULL;
	ShExecInfo.lpDirectory = NULL;
	ShExecInfo.nShow = SW_HIDE;

	ShExecInfo.hInstApp = NULL;
	for(i=MAX_DAY;i> qjLogSaveTime;i--)
	{
		PreSeconds =0;
		PreSeconds = CurSeconds-(i*3600*24);/*获取要删除的时间*/
		dellocaltime =localtime(&PreSeconds);
		/*拼写要删除的文件夹*/
		sprintf(fileName,"%s\\%04d%02d%02d",(CHAR *)dirName,dellocaltime->tm_year+1900,dellocaltime->tm_mon+1,dellocaltime->tm_mday);
		/*拼写要删除的文件夹*/
		sprintf(rarfileName,"%s\\%04d%02d%02d.rar",(CHAR *)dirName,dellocaltime->tm_year+1900,dellocaltime->tm_mon+1,dellocaltime->tm_mday);
	

		/*ret：0 是目录，其他非目录*/
		/*只判断目录是否存在*/
		ret1 = access(rarfileName,0);
		if( !ret1)
		{
			/*是目录，删除的文件夹*/
			/*sprintf(DelCmd2, "del /q /f /s %s",rarfileName);
			system(DelCmd2);*/

			/*是目录，删除的文件夹*/
			sprintf(DelCmd2, " cmd.exe /c del /q /s %s", rarfileName);
			/*	system(DelCmd2);*/
			ShExecInfo.lpFile = L"cmd.exe";
			memset(szDest, '\0', sizeof(WCHAR) * 800);
			long lLen = MultiByteToWideChar(CP_ACP, 0, DelCmd2, strlen(DelCmd2), szDest, sizeof(szDest));
			ShExecInfo.lpParameters = szDest;
			ShellExecuteEx(&ShExecInfo);
			WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
		
		}
		/*只判断目录是否存在*/
		ret = access(fileName,0);
		/*ret：0 是目录，其他非目录*/
		if( !ret )
		{
			/*是目录，删除的文件夹*/
			/*sprintf(DelCmd2, "rmdir /s/q %s",fileName);				
			system(DelCmd2);*/
			/*是目录，删除的文件夹*/
			sprintf(DelCmd2, " cmd.exe /c rmdir /s /q %s", fileName);
			/*	system(DelCmd2);*/
			ShExecInfo.lpFile = L"cmd.exe";
			memset(szDest, '\0', sizeof(WCHAR) * 800);
			long lLen = MultiByteToWideChar(CP_ACP, 0, DelCmd2, strlen(DelCmd2), szDest, sizeof(szDest));
			ShExecInfo.lpParameters = szDest;
			ShellExecuteEx(&ShExecInfo);
			WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
		
		}
		
		

	}	

}

/*压缩指定的文件*/
void WinRardirByhour( CHAR *dirName )
{
	time_t CurSeconds=0;   /*时间变量*/
	time_t PreSeconds =0;  /*时间变量*/
	struct tm *dellocaltime=NULL;  /*时间变量*/
	CHAR fileName[400]={0}; /*目录变量*/
	CHAR Name[400]={0}; /*目录变量*/
	CHAR DirName[400]={0}; /*目录变量*/
	CHAR fileNameRar[400]={0}; /*目录变量*/

	char WinrarCmd[400]={0}; /*临时变量*/
	char DelCmd2[400]={0};  /*临时变量*/
	int i=0; /*循环变量*/
	int j=0; /*循环变量*/
	int ret=0;

	WCHAR szDest[800];

	memset(fileName,'\0',sizeof(CHAR) * 400); /*初始化变量*/
	memset(Name,'\0',sizeof(CHAR) * 400); /*初始化变量*/
	memset(DirName,'\0',sizeof(CHAR) * 400); /*初始化变量*/
	memset(fileNameRar,'\0',sizeof(CHAR) * 400); /*初始化变量*/
	memset(szDest, '\0', sizeof(WCHAR) * 800);
	time(&CurSeconds);   /*获取本地时间*/
	SHELLEXECUTEINFO ShExecInfo = { 0 };
	ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
	ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
	ShExecInfo.hwnd = NULL;
	ShExecInfo.lpVerb = NULL;	
	ShExecInfo.lpDirectory= NULL;
	ShExecInfo.nShow = SW_HIDE;
	
	ShExecInfo.hInstApp = NULL;



	for(i=MIN_DAY;i>=0;i--)
	{	
		for(j=0;j< 24; j++)
		{
			PreSeconds = CurSeconds-((i*24-j )*3600);
			if(  PreSeconds <= (CurSeconds - 3600))
			{
				/*获取压缩的时间*/
				dellocaltime =localtime(&PreSeconds); 			
				/*拼写要压缩的文件夹*/
				sprintf(DirName,"%s\\%04d%02d%02d",(CHAR *)dirName,dellocaltime->tm_year+1900,dellocaltime->tm_mon+1,dellocaltime->tm_mday);
				/*拼写要压缩的文件夹*/
				sprintf(fileNameRar,"%04d%02d%02d_%02d",dellocaltime->tm_year+1900,dellocaltime->tm_mon+1,dellocaltime->tm_mday,dellocaltime-> tm_hour);
				/*拼写要压缩的文件夹*/
				sprintf(fileName,"%s\\%02d",(CHAR *)DirName,dellocaltime-> tm_hour);
				/*拼写要压缩的文件夹*/
				sprintf(Name,"%s\\%s",DirName,fileNameRar);
				
	
				/*只判断目录是否存在*/
				ret = access(fileName,0);
				/*ret：0 是目录，其他非目录*/
				if( !ret)
				{
					/*是目录，压缩本文件夹*/
					sprintf(WinrarCmd, "a -ep1 %s -ap %s.rar %s",Name,Name,fileName);
				/*	int ret =system(WinrarCmd);*/
					/*删除本文件夹*/

					ShExecInfo.lpFile = L"rar.exe";
					memset(szDest, '\0', sizeof(WCHAR) * 800);
					long lLen = MultiByteToWideChar(CP_ACP, 0, WinrarCmd, strlen(WinrarCmd), szDest, sizeof(szDest));
					ShExecInfo.lpParameters = szDest;
				/*	ShExecInfo.lpParameters = L"a -ep1 .\\PrtclLog\\20210902\\16.rar  .\\PrtclLog\\20210902";*/
				bool ret =	ShellExecuteEx(&ShExecInfo);
					WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
					/*ret：0 是目录，其他非目录*/
					/*只判断目录是否存在*/
					ret = access(fileName,0);
					if( !ret)
					{
						/*是目录，删除的文件夹*/
						sprintf(DelCmd2, " cmd.exe /c del /q /s %s",fileName);
						/*	system(DelCmd2);*/
						ShExecInfo.lpFile = L"cmd.exe";
						memset(szDest, '\0', sizeof(WCHAR) * 800);
						long lLen = MultiByteToWideChar(CP_ACP, 0, DelCmd2, strlen(DelCmd2), szDest, sizeof(szDest));
						ShExecInfo.lpParameters = szDest;
						ShellExecuteEx(&ShExecInfo);
						WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
		
					}
					/*只判断目录是否存在*/
					ret = access(fileName,0);
					/*ret：0 是目录，其他非目录*/
					if( !ret )
					{
						/*是目录，删除的文件夹*/
						sprintf(DelCmd2, " cmd.exe /c rmdir /s /q %s",fileName);				
						/*	system(DelCmd2);*/
						ShExecInfo.lpFile = L"cmd.exe";
						memset(szDest, '\0', sizeof(WCHAR) * 800);
						long lLen = MultiByteToWideChar(CP_ACP, 0, DelCmd2, strlen(DelCmd2), szDest, sizeof(szDest));
						ShExecInfo.lpParameters = szDest;
						ShellExecuteEx(&ShExecInfo);
						WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
		
					}
		
				}
			}
			else
			{
				break;
			}
	   	
		}
		
		if( i != 0)
		{
			PreSeconds = CurSeconds-((i*24)*3600);
			/*获取要删除的时间*/
			dellocaltime =localtime(&PreSeconds); 
			/*拼写要删除的文件夹,dellocaltime->tm_hour*/
			sprintf(DirName,"%s\\%04d%02d%02d",(CHAR *)dirName,dellocaltime->tm_year+1900,dellocaltime->tm_mon+1,dellocaltime->tm_mday);
			 /*拼写要删除的文件夹,dellocaltime->tm_hour*/
			//sprintf(Name,"%04d%02d%02d",dellocaltime->tm_year+1900,dellocaltime->tm_mon+1,dellocaltime->tm_mday);
			
			/*只判断目录是否存在*/
			ret = access(DirName,0);
			/*ret：0 是目录，其他非目录*/
			if( !ret)
			{
				/*是目录，压缩本文件夹*/
				sprintf(WinrarCmd, "a  -ep1 %s  -ap  %s.rar   %s",DirName,DirName,DirName);
			/*	system(WinrarCmd);*/
				/*删除本文件夹*/
				ShExecInfo.lpFile = L"rar.exe";
				memset(szDest, '\0', sizeof(WCHAR) * 800);
				long lLen = MultiByteToWideChar(CP_ACP, 0, WinrarCmd, strlen(WinrarCmd), szDest, sizeof(szDest));
				ShExecInfo.lpParameters = szDest;
				/*	ShExecInfo.lpParameters = L"a -ep1 .\\PrtclLog\\20210902\\16.rar  .\\PrtclLog\\20210902";*/
				bool ret = ShellExecuteEx(&ShExecInfo);
				WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
			
				/*ret：0 是目录，其他非目录*/
					/*只判断目录是否存在*/
				ret = access(DirName,0);
				if( !ret)
				{
					/*是目录，删除的文件夹*/
					sprintf(DelCmd2, " cmd.exe /c del /q  /s %s",DirName);
					/*system(DelCmd2);*/
					ShExecInfo.lpFile = L"cmd.exe";
					memset(szDest, '\0', sizeof(WCHAR) * 400);
					long lLen = MultiByteToWideChar(CP_ACP, 0, DelCmd2, strlen(DelCmd2), szDest, sizeof(szDest));
					ShExecInfo.lpParameters = szDest;
					ShellExecuteEx(&ShExecInfo);
					WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
		
				}
				/*只判断目录是否存在*/
				ret = access(DirName,0);
				/*ret：0 是目录，其他非目录*/
				if( !ret )
				{
					/*是目录，删除的文件夹*/
					sprintf(DelCmd2, " cmd.exe /c rmdir /s /q %s",DirName);				
					/*system(DelCmd2);*/
					ShExecInfo.lpFile = L"cmd.exe";
					memset(szDest, '\0', sizeof(WCHAR) * 400);
					long lLen = MultiByteToWideChar(CP_ACP, 0, DelCmd2, strlen(DelCmd2), szDest, sizeof(szDest));
					ShExecInfo.lpParameters = szDest;
					ShellExecuteEx(&ShExecInfo);
					WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
		
				}
		
			}
		}

		

	}
		

}
FILE * openlogfile(CHAR *dirName)
{

	FILE *fp = NULL;
	CHAR fileName[400];
	CHAR fileName1[200];
	CHAR RemirfileName[200];
	static  bool flag = false;
	SYSTEMTIME tm;
	GetLocalTime(&tm);
	
	memset(fileName,'\0',sizeof(CHAR) * 400);
	memset(fileName1,'\0',sizeof(CHAR) * 200);
	memset(RemirfileName,'\0',sizeof(CHAR) * 200);
	sprintf(RemirfileName,"%s\\%04d%02d%02d",dirName,tm.wYear,tm.wMonth,tm.wDay);
	sprintf(fileName1,"%s\\%02d",RemirfileName,tm.wHour);
	
	
	if (!CreateDirectoryA((CHAR *)RemirfileName, NULL)) 
    { 
		/* 不成功说明该目录存在,因此不需要创建 */

    } 
	else
	{
		
	} 
	
	if (!CreateDirectoryA((CHAR *)fileName1, NULL)) 
		{ 
			/* 不成功说明该目录存在,因此不需要创建 */

		} 
		else
		{
			if( false== flag)
			{
				 flag = true;
			}
			else
			{
				 /*创建当前目录的同时，删除日志 */
				WinRardirByhour(dirName );
				DeldirByday(dirName);
			}
			
		}
	sprintf(fileName,"%s\\%04d_%02d_%02d_%02d_%02d_%02d.log",(CHAR *)fileName1,tm.wYear,tm.wMonth,tm.wDay,tm.wHour,tm.wMinute,tm.wSecond);
	fp = fopen(fileName,"a+");
	return fp;
}

UINT8 RecordLogClass::WriteThead()
{
	UINT8 buff[2048];
	UINT8 ret = 0;	
	
	while(1)
	{
		UINT32 len = 0;
		if(logFlg == 0)
		{
			break;
		}
#if 0
		/* 加锁 */
		WaitForSingleObject(hWritedataSemaphore,INFINITE);
		len = QueueStatus(_pwriteque);
		if( len >0)
		{
		/*	取出数据到Buff。*/
		    ret = QueueRead(len,buff,_pwriteque);
	    /*记录数据长度*/
		}
		/*  解锁 */
		ReleaseSemaphore(hWritedataSemaphore,1,NULL);
#else
		len = GetLogData(buff);
#endif 
		if(len >0)
		{
			fwrite(buff,len,1,fp);
			fflush(fp);
			filecounter +=len;
			if(filecounter > 1024*1024*20)
			{
				fclose(fp);
				filecounter = 0;
				fp = openlogfile(dirName);
			}
		}
		else
		{
			Sleep(1);
		}
	}
	return ret;
}
/*
 * 进程处理函数
 */
INT32 WriteData(LPVOID pParam)
{
	UINT8 ret = 0;
	UINT32 len = 0;
	//UINT8 buff[2048];
	RecordLogClass *pRecordLogClass = (RecordLogClass*)pParam;
	pRecordLogClass->WriteThead();
#if 0
	while(1)
	{
		len = pRecordLogClass->GetLogData(buff);

		if(len>0)
		{
			pRecordLogClass->WriteFile(buff,len);	
		}

		Sleep(0);

	}
#endif
	return ret;
}

UINT32 RecordLogClass::GetLogData(UINT8 *buff)
{
	UINT32 len = 0;
	UINT8 ret =0;
	/* 加锁 */
	WaitForSingleObject(hWritedataSemaphore,INFINITE);
	len = QueueStatus(_pwriteque);
	if( len < 2048)
	{
		/*	取出数据到Buff。*/
		ret = QueueRead(len,buff,_pwriteque);
		/*记录数据长度*/
	}
	else
	{
		/*	取出数据到Buff。*/
		ret = QueueRead(2048,buff,_pwriteque);
		/*记录数据长度*/
		len = 2048;
	}

	/*  解锁 */
	ReleaseSemaphore(hWritedataSemaphore,1,NULL);

	return len;
}

UINT8 RecordLogClass::WriteFile(UINT8 *buff,UINT32 len)
{
   	fwrite(buff,len,1,fp);
	fflush(fp);
	filecounter +=len;
	if(filecounter > 1024*1024*20)
	{
		fclose(fp);
		filecounter = 0;
		fp = openlogfile(dirName);
	} 
	return 0;
}