/***************************************************************************
                File Hash Class
                -----------------------------------------
    begin      : 2010/02/27
    copyright  : (C) 2005 SolutionBox Inc.
    author     : Service 1 Team
    email      : svc1@solbox.com
    version    : 1.0

    CopyRight(C) 2005 SolutionBox Inc. All Rights reserved.
    Redistribution and use in source and binary forms, with or with out
    modification, are not permitted in outside of SolutionBox Inc.
***************************************************************************/

#ifndef __FILEHASH_H__
#define __FILEHASH_H__

#include <string>
#include "global.h"
#include "md5.h"

#define MD_CTX MD5_CTX
#define MDInit MD5Init
#define MDUpdate MD5Update
#define MDFinal MD5Final

using namespace std;

#define HASH_LEVEL_NONE		        0
#define HASH_LEVEL_PARTITIAL	    1
#define HASH_LEVEL_FULL				2
#define HASH_LEVEL_FRONT_PARTITIAL	3	// 2012-08-13 Content 앞 특정 부분만 Hash 추출을 위해 추가	

/// @brief CFileHash class
/// 주 목적은 파일의 해시값을 구하는 것이다.
///
/// 상황에 따라 세가지 해시방법을 제공한다.
/// 1. 파일 전체를 해시.
/// 2. 파일의 앞일부와 뒤의 일부를 해시처리 한다.(속도 개선)
/// 3. buffer와 buffer의 길이를 입력값으로 하는 buffer 모드.
///
/// 또한 전달받은 해시와 로컬파일의 해시를 Level에 따라 체크 하는 인터페이스도
/// 제공하고있다.
///
///  에러 상황은 GetLastErrorMessage() 함수를 통해 어떤이유로 에러가 발생했는지
/// 확인 할 수 있다.
class CFileHash
{
	public :
    	CFileHash();
    	
        /// @brief Sender에서 사용하는 함수로서 파일에 대한 해쉬값을 레벨에 따라 생성한다.
        /// @param szFileFullPath [in] 파일의 절대경로 값.
        /// @param nHashLevel [in] 해싱 방법에 대한 레벨 값.
        /// @param szResult [out] 해싱된 결과값을 되돌려주는 변수. nHashLevel이 HASH_LEVEL_NONE일 경우 항상 "0000"이 들어감.
        /// @return 성공은 return true, 그 외에는 return false
        bool GetFileHash(const string &szFileFullPath, int nHashLevel, string& szResult);
        
        /// @brief Receiver에서 사용하는 함수로서 해당파일의 해시값과 Sender에서 받은 해싱값을 비교한 결과를 전달한다.
        /// @param szFileFullPath [in] 파일의 절대경로 값.
        /// @param nHashLevel [in] 해싱 방법에 대한 레벨 값.
        /// @param szCompareHash [out] Sender로 부터 받은 해시 값.
        /// @return 같은 값일경우 return true, 그 외에는 return false
        bool CheckFileHash(const string& szFileFullPath, int nHashLevel, const string szCompareHash);
        
        /// @brief Sender쪽에서 보낼때 파일을 buffer단위로 해싱처리를 하기위한 인터페이스다.
        /// @param szBuffer [in] 해싱할 데이터
        /// @param nLen [in] 해싱할 데이터의 길이.
        /// @return 없음.
        void UpdateBufferHash(unsigned char* szBuffer, int nLen );
        
        /// @brief UpdateBufferHash() 함수를 이용해서 해싱한 결과값을 얻어온다.
        /// @param szResult [out] 결과값을 되돌려주는 변수
        /// @return 없음.
        void GetBufferHash(string& szResult);
        
        /// @brief Buffer Hash 했던 값을 초기화 하는 함수.
        /// @return 없음.
        void ClearBufferHash();
        
        /// @brief HASH_LEVEL_PARTITIAL일 경우 파일의 앞뒤의 일정용량을 해시대상으로 삼는데 그 용량값의 설정값을 얻는다.
        /// @return 없음.
        int GetPartitialSize();
        
        /// @brief HASH_LEVEL_PARTITIAL일 경우 파일의 앞뒤의 일정용량을 해시대상으로 삼는데 그 용량값의 설정값을 세팅한다.
        /// @param nPartitialSize [in] MByte 단위로 partitial 크기를 설정한다. (0 또는 (-) 음수는 처리안함)
        /// @return 성공은 return true, 실패는 return false
        bool SetPartitialSize( int nPartitialSize );
        
        /// @brief 각 함수 호출시 마지막에 난 에러메세지를 얻을 수 있다.
        /// @return 마지막에 발생한 에러메세지.
        string GetLastErrorMessage();

		// NEW 2016-05-04 huibong 토토디스크 지원용 기능 추가 (#27460, #27533)
		/// @brief 토토디스크 고객사 지원용 파일 Hash 정보 추출 함수
		/// @param szFileFullPath [in] 파일의 절대경로 값.
		/// @param nFileTotalSize [in] 파일 크기 값.
		/// @param szResultTotosoraMd5 [out] TOTOROSA MD5 추출 결과값을 반환하기 위한 변수.
		/// @param szResultDnaCheckKey [out] 토토 DNA Check Key 추출 결과값을 반환하기 위한 변수.
		/// @return 성공은 return true, 그 외에는 return false
		bool GetHashTOTO( const string &szFileFullPath, const unsigned long long nFileTotalSize, string& szResultTotosoraMd5, string& szResultDnaCheckKey );
		

	private :
	    int m_nPartitialSize;
        MD_CTX m_contextForBuffer;
        char m_szLastErrorMessage[1024];
        
	    bool GetHashFull(const string &szFileFullPath, string& szResult);
	    bool GetHashPartitial(const string &szFileFullPath, string& szResult);
	    bool GetHashFrontPartitial(const string &szFileFullPath, string& szResult);
};
#endif //__FILEHASH_H__
