#pragma once

#include <vector>
#include <algorithm>

class CDumpStatisticsDlg ;

enum DUMP_FLUG
{
	SERVER_NAME,
	SERVER_VERSION,
	EXCEPTION,
	FAULT_ADDRESS
} ;

typedef struct __DUMPMETADATA
{
	CHAR	byFaultAddress[50][ 10 ] ;			// 뻣은 주소 ㅡㅡ;
	int		nFaultCnt;
	CHAR	byException[ 10 ] ;				// 익셉션 주소
	CHAR	szServerName[ 32 ] ;			// 서버 이름
	CHAR	szFileName[ MAX_PATH ] ;		// dump 파일명
	CHAR	szVersion[ 8 ] ;
	CHAR	szAvailabelVirtualMemory[ 15 ];	// 가상 메모리 여유분
	CHAR	szTotalPhysicalMemory[ 15 ];	// 실제 메모리량
	CHAR	szAdapterRAM[ 15 ];				// 비디오 램
	CHAR	szVideoProcessor[ 64 ];			// 비디오 프로세서
	CHAR	szAvailableMemory[ 15 ];		// 여유 메모리


	DOUBLE	fVersion ;						// 서버 버전
	__DUMPMETADATA(){	ClearData();	};
	void ClearData()
	{
		memset( byFaultAddress, 0, sizeof( CHAR ) * 50 * 10 ); 
		nFaultCnt = 0 ; 
		memset( byException, 0, sizeof( CHAR ) * 10 ); 
		memset( szServerName, 0, sizeof( CHAR ) * 32 ); 
		memset( szFileName, 0, sizeof( CHAR ) * MAX_PATH ); 
		strcpy( szVersion, "0.00" ); 
		strcpy( szAvailabelVirtualMemory, "0" );
		strcpy( szTotalPhysicalMemory, "0" );
		strcpy( szAdapterRAM, "0" );
		strcpy( szVideoProcessor, "0" );
		strcpy( szAvailableMemory, "0" );
		fVersion = 0;
	}
}DUMPMETADATA, *LPDUMPMETADATA ;

typedef struct __FILENAME
{
	CHAR			szFileName[ MAX_PATH ] ;
}FILENAME, *LPFILENAME ;

typedef struct __FAULTLIST
{
	DOUBLE			dwVersion;
	CHAR			szFileName[ MAX_PATH ] ;
}FAULTLIST, *LPFAULTLIST;

typedef struct __DUMPDIRECTORYINFO
{
	CHAR			szDirectory[ MAX_PATH ] ;			// 해당 Direcoty
	std::vector< LPFILENAME >	vecDumpFileInfo ;	// Vector 파일
} DUMPDIRECTORYINFO, *LPDUMPDIRECTORYINFO ;

class CDumpLog
{
public:
	DOUBLE						fVersion;						// 버전
	CHAR						szFaultAddress[ MAX_PATH ];		// Fault Address
	CHAR						szFileName[ MAX_PATH ] ;		// 파일명
	CHAR						szVersion[ MAX_PATH ] ;			// 버전
	CHAR						szGraphicCard[ MAX_PATH ] ;		//그래픽 카드
	UINT						nBaseSystemMemory;				//기본 시스템 메모리
	UINT						nUsedSystemMemory;				//사용 시스템 메모리
	UINT						nBaseLocalMemory;				//기본 Local 메모리
	UINT						nLeftMemory;					//기본 Local 메모리 - 남은량
	UINT						nBaseAGPMemory;					//기본 AGP 메모리
	UINT						nUsedAGPMemory;					//기본 AGP 메모리
public:
	VOID						Print2File( FILE* pFile );
	CDumpLog(){};
	~CDumpLog(){};
};

class CDumpReport
{
private:
	std::vector< CDumpLog* >	vecDumpFile;	// 덤프 정보
	std::vector< LPFAULTLIST >	vecFaultList;
	VOID AddFaultList( const char* szFault );
public:
	BOOL Write2File( const char* filename );
	CDumpReport(){};
	~CDumpReport();
	VOID PushFaultLog( LPDUMPMETADATA lpMeta );

};

class CDumpFileParser
{
private :
	CHAR		m_szCurrentDirectory[ MAX_PATH ] ;		// 현재 디렉토리
	CHAR		m_szCopyDirectory[ MAX_PATH ] ;			// 순서에 맞게 복사해서 넣는 위치
	std::vector< LPDUMPDIRECTORYINFO >		m_vecDumpDirectoryInfo ;
	UINT		m_uiDumpSize ;
	CDumpStatisticsDlg* m_pDlg ;
	CDumpReport	m_DumpReport;

protected:
	VOID	FindDumpDirectory( const char* path ) ;			//하위 디렉토리를 전부 검색하여	파일을 덤프 파일 목록과 디렉토리 목록을 만든다.
	VOID	FindDumpFile( LPDUMPDIRECTORYINFO pDirectoryInfo ) ;		// 해당 디렉토리에서의 파일 찾기

public :
	CDumpFileParser( CDumpStatisticsDlg* pDlg ) ;
	~CDumpFileParser(void);

	VOID	SetDumpDirectory( LPCTSTR lpszDirectory ) 
	{
		strcpy( m_szCurrentDirectory, lpszDirectory ) ;
		sprintf( m_szCopyDirectory,"%s\\sort", m_szCurrentDirectory ) ;
		::SetCurrentDirectory( m_szCurrentDirectory );
		::CreateDirectory( "sort", NULL ) ;
	}

	VOID	LoadDumpFile() ;
	HRESULT	CheckLine( CHAR* strLine, LPDUMPMETADATA lpMetaData ) ;
	HRESULT	CheckMoreDump( FILE* pFile, LPDUMPMETADATA lpMetaData ) ;
	
	const char*	MakeDirectory( LPDUMPMETADATA lpMetaData, int nCnt );		// 해당 덤프하는 디렉토리를 만들고 해당 디렉토리 위치를 리턴한다.
	BOOL	CopyFileExt( LPDUMPMETADATA lpMetaData, LPSTR lpszFileName );
	//=======================================================
	// Directory 관련
	//=======================================================

	VOID	FindDumpDirectory() ;			//하위 디렉토리를 전부 검색하여	파일을 덤프 파일 목록과 디렉토리 목록을 만든다.
};
