/***************************************************************************
    ftsd control interface ( File Replication & Cache & Move & Delete Control) Header ( FtsdSocketControl.h )
                -----------------------------------------
	begin      : 2010/03/09
	copyright  : (C) 2005 SolutionBox Inc.
	author     : Service 1 Team
	email      : svc1@solbox.com
	version    : 3.2.0.R0811

	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 __FTSD_SOCKET_CONTROL_H__
#define __FTSD_SOCKET_CONTROL_H__

#include "BaseSocket.h"
#include "FtsdProtocol.h"

#include <iostream>
#include <vector>
#include <map>


///< BYTE 타입 정의
#ifndef _BYTE_DEFINED
#define _BYTE_DEFINED
typedef unsigned char BYTE;
#endif  // _BYTE_DEFINED


#define DEFAULT_SOCKET_TEMP_BUFFER_SIZE		1024	// SocketControl 에서 사용할 임시버퍼 크기.

class CFtsdSocketControl : public CBaseSocket
{
	private:
		
		/// @brief Packet Header 변수
		struct FileTransferPacketHeader m_packetHeader;

		/// @brief m_packetHeader 구조체의 크기를 저장하기 위한 상수
		const int m_nPacketHeaderLen;  

		/// @brief Packet Header 에 저장된 Data 부분의 길이 정보값.
		unsigned int m_nPacketDataLen;

		/// @brief Packet Data 부분의 수신처리시 임시로 사용할 버퍼.
		BYTE m_tempBuffer[DEFAULT_SOCKET_TEMP_BUFFER_SIZE];


	public:

		/// @brief 생성자.
		CFtsdSocketControl();
		
		/// @brief 소멸자.
		~CFtsdSocketControl();


		/// @brief 전달받은 Target 으로 Socket 접속을 수행
		/// @param szTarget [in] 접속 대상 Host name 또는 IP
		/// @param nPort	[in] 접속 Port
		/// @return 접속 성공시 true, 실패시 false 반환. ( 오류 내역은 로깅처리됨.)
		bool ConnectTarget( const std::string& szTarget, int nPort );
	

		/// @brief 대상과 연결된 Socket 을 통해 ftsd 로 File Replication 명령 전송.
		/// @param szFileName [in] 복제할 원본 Source 파일명 (/stg/node0/186/abcde..)
		/// @param nFileSize  [in] 복제할 원본 Source 파일의 크기.
		/// @param szTargetTranId [in] RC 간 복제 처리시 변경할 대상 Tran ID 정보 값.
		/// @param nFileHashCheckLevel [in] File 에 대한 Hash Check Level 정보 ( conf 파일에 지정됨)
		/// @param bUseInternalIp [in] 내부망을 이용하여 파일 송수신을 수행할지 여부 \n
		///<                      해당값을 true 로 지정시 ftsd 상에서 내부망을 우선 사용하여 파일 복제 시도
		///<                      만약 내부망 사용 불가시 자동으로 외부망 사용.
		///<                      RC-RC 간 처리시에는 사용하지 않도록 false 로 지정할 것.
		/// @param vecTargetFhs [in] 복제 대상 Target FHS Host Name 정보
		/// @return Replication 복제 요청 메시지 전송 성공시 true, 실패시 false 반환.
		bool SendFileReplicationRequest(const std::string& szFileName, unsigned long long nFileSize, int nFileHashCheckLevel, bool bUseInternalIp, std::vector< std::string >& vecTargetFhs);
		bool SendFileReplicationRequest(const std::string& szFileName, unsigned long long nFileSize, const std::string& szTargetTranId, int nFileHashCheckLevel, bool bUseInternalIp, std::vector< std::string >& vecTargetFhs);


		/// @brief File Replication 요청에 대한 처리 결과를 ftsd 로 부터 수신한다. 
		/// @param nTimeout [in] 함수 호출에 대한 Blocking 을 방지하기 위한 Timeout 설정값. 단위( second )\n
		///<                     지정된 시간동안 응답을 수신하지 못한 경우 0 을 반환.
		/// @param bSuccess [out] File Replication 이 정상적으로 수행되었는지 여부 \n
		///<                      trnsfer 상에서 오류가 발생한 경우 이 값은 false 가 되며 \n
		///<                      szErrorMessage 변수상에 오류내용이 저장됨. \n
		///<                      정상적으로 처리된 경우 true 가 저장되며 \n
		///<                      mapSuccessFhs, mapFailFhs 상에 관련 정보가 저장됨.
		/// @param szErrorMessage [out] bSuccess == false 인 경우 발생된 오류메시지 정보를 저장
		/// @param mapSuccessFhs [out] bSuccess == true 인 경우 \n
		///<                           Replication 처리에 성공한 FHS 및 저장된 File 이름 정보를 저장
		/// @param mapFailFhs [out] bSuccess == true 인 경우 \n
		///<                        Replication 처리에 실패한 FHS Host Name 및 발생된 오류메시지 정보를 저장.
		///
		/// @return -1 : Socket 통신 관련 오류 발생하여 ftsd 와 연결이 끊어진 경우 \n
		///<             => ftsd 와 연결이 끝어진것으로 판단하고 오류처리한다. \n
		///<
		///<         0 : 입력변수인 nTimeout 에 지정된 시간안에 ftsd 로부터
		///<             Replication 에 대한 처리 결과 정보를 수신하지 못한 경우. \n
		///<             이 기능은 본 함수 호출시 Blocking 발생을 막기 위한 기능으로서 \n
		///<             이 값이 반환된 경우 추가 다른 작업을 진행한 후 본 함수를 다시 호출하여 \n
		///<             응답을 대기할 수 있다. \n
		///<
		///<         1 : 파일 복제 처리에 대한 응답을 수신한 경우, Output 인자인 bSuccess 를 확인하여 처리 결과 확인
		///<             
		///<         2 : ftsd 로 부터 Data 을 수신하였으나 File Replication 요청에 대한 응답이 아닌 경우 \n
		///<             해당 정보는 본 클래스의 멤버변수 상에 내부적으로 저장된다. ( 단 Alive Packet 은 아님) \n
		///<             본 결과가 수신된 경우 무시 처리하고 계속 응답을 대기하면 된다.
		int GetFileReplicationResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage, std::map< std::string, std::string>& mapSuccessFhs, std::map< std::string, std::string>& mapFailFhs );


		/// @brief 대상과 연결된 Socket 을 통해 ftsd 로 File Cache 명령 전송.
		/// @param szFileName [in] Cache 처리할 원본 Source 파일명 (/stg/node0/186/abcde..)
		/// @param nFileSize  [in] Cache 처리할 원본 Source 파일의 크기.
		/// @param nFileHashCheckLevel [in] File 에 대한 Hash Check Level 정보 ( conf 파일에 지정됨)
		/// @param bUseInternalIp [in] 내부망을 이용하여 파일 송수신을 수행할지 여부 \n
		///<                      해당값을 true 로 지정시 ftsd 상에서 내부망을 우선 사용하여 파일 복제 시도
		///<                      만약 내부망 사용 불가시 자동으로 외부망 사용.
		/// @param vecTargetFhs [in] Cache 대상 Target FHS Host Name 정보
		/// @return Cache 요청 메시지 전송 성공시 true, 실패시 false 반환.
		bool SendFileCacheRequest(const std::string& szFileName, unsigned long long nFileSize, int nFileHashCheckLevel, bool bUseInternalIp, std::vector< std::string >& vecTargetFhs);


		/// @brief File Cache 요청에 대한 처리 결과를 ftsd 로 부터 수신한다. 
		/// @param nTimeout [in] 함수 호출에 대한 Blocking 을 방지하기 위한 Timeout 설정값. 단위( second )\n
		///<                     지정된 시간동안 응답을 수신하지 못한 경우 0 을 반환.
		/// @param bSuccess [out] File Cache 처리가 정상적으로 수행되었는지 여부 \n
		///<                      trnsfer 상에서 오류가 발생한 경우 이 값은 false 가 되며 \n
		///<                      szErrorMessage 변수상에 오류내용이 저장됨. \n
		///<                      정상적으로 처리된 경우 true 가 저장되며 \n
		///<                      mapSuccessFhs, mapFailFhs 상에 관련 정보가 저장됨.
		/// @param szErrorMessage [out] bSuccess == false 인 경우 발생된 오류메시지 정보를 저장
		/// @param mapSuccessFhs [out] bSuccess == true 인 경우 \n
		///<                           Cache 처리에 성공한 FHS 및 저장된 File 이름 정보를 저장
		/// @param mapFailFhs [out] bSuccess == true 인 경우 \n
		///<                        Cache 처리에 실패한 FHS Host Name 및 발생된 오류메시지 정보를 저장.
		///
		/// @return -1 : Socket 통신 관련 오류 발생하여 ftsd 와 연결이 끊어진 경우 \n
		///<             => ftsd 와 연결이 끝어진것으로 판단하고 오류처리한다. \n
		///<
		///<         0 : 입력변수인 nTimeout 에 지정된 시간안에 ftsd 로부터
		///<             Cache 에 대한 처리 결과 정보를 수신하지 못한 경우. \n
		///<             이 기능은 본 함수 호출시 Blocking 발생을 막기 위한 기능으로서 \n
		///<             이 값이 반환된 경우 추가 다른 작업을 진행한 후 본 함수를 다시 호출하여 \n
		///<             응답을 대기할 수 있다. \n
		///<
		///<         1 : 파일 Cache 처리에 대한 응답을 수신한 경우, Output 인자인 bSuccess 를 확인하여 처리 결과 확인
		///<             
		///<         2 : ftsd 로 부터 Data 을 수신하였으나 File Cache 요청에 대한 응답이 아닌 경우 \n
		///<             해당 정보는 본 클래스의 멤버변수 상에 내부적으로 저장된다. ( 단 Alive Packet 은 아님) \n
		///<             본 결과가 수신된 경우 무시 처리하고 계속 응답을 대기하면 된다.
		int GetFileCacheResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage, std::map< std::string, std::string>& mapSuccessFhs, std::map< std::string, std::string>& mapFailFhs );

		
		/// @brief 대상과 연결된 Socket 을 통해 ftsd 로 Content Check 명령 전송.
		/// @param szFileName [in] 원본 Source 파일명 (/stg/node0/186/abcde..)
		/// @param bHashCheck [in] Hash 값을 추출할지 여부
		/// @param nHashCheckSize [in] Hash 값을 추출할 경우 Size 설정값 ( MByte 단위 )\n
		///<                          0    : Content 에 대한 전체 Hash 값을 추출함.
		///<                          숫자 : Content 의 앞 부분부터 지정된 크기 (MByte ) 까지 Hash 값을 추출
		/// @return Check 요청 메시지 전송 성공시 true, 실패시 false 반환.
		bool SendFileCheckRequest(const std::string& szFileName, bool bHashCheck, unsigned long long nHashCheckSize );

		/// @brief File Check 요청에 대한 처리 결과를 ftsd 로 부터 수신한다. 
		/// @param nTimeout [in] 함수 호출에 대한 Blocking 을 방지하기 위한 Timeout 설정값. 단위( second )\n
		///<                     지정된 시간동안 응답을 수신하지 못한 경우 0 을 반환.
		/// @param bSuccess [out] File Check 처리가 정상적으로 수행되었는지 여부 \n
		///<                      ftsd 상에서 오류가 발생한 경우 이 값은 false 가 되며 \n
		///<                      szErrorMessage 변수상에 오류내용이 저장됨. \n
		///<                      정상적으로 처리된 경우 true 가 저장되며 \n
		///<                      nFileSize, szHashValue 상에 결과 정보가 저장됨.
		/// @param szErrorMessage [out] bSuccess == false 인 경우 발생된 오류메시지 정보를 저장
		/// @param nFileSize      [out] bSuccess == true 인 경우 요청한 Content 에 대한 file size 정보를 저장. ( Byte 단위 )
		/// @param szHashValue    [out] bSuccess == true 이고... Hash 값 추출을 요청한 경우 추출된 Hash 값 정보를 저장.
		/// @return -1 : Socket 통신 관련 오류 발생하여 ftsd 와 연결이 끊어진 경우 \n
		///<             => ftsd 와 연결이 끝어진것으로 판단하고 오류처리한다. \n
		///<
		///<         0 : 입력변수인 nTimeout 에 지정된 시간안에 ftsd 으로부터 처리 결과 정보를 수신하지 못한 경우. \n
		///<             이 기능은 본 함수 호출시 Blocking 발생을 막기 위한 기능으로서 \n
		///<             이 값이 반환된 경우 추가 다른 작업을 진행한 후 본 함수를 다시 호출하여 \n
		///<             응답을 대기할 수 있다. \n
		///<
		///<         1 : 파일 Check 처리에 대한 응답을 수신한 경우, Output 인자인 bSuccess 를 확인하여 처리 결과 확인
		///<             
		///<         2 : ftsd 으로 부터 Data 을 수신하였으나 File Check 요청에 대한 응답이 아닌 경우 \n
		///<             해당 정보는 본 클래스의 멤버변수 상에 내부적으로 저장된다. ( 단 Alive Packet 은 아님) \n
		///<             본 결과가 수신된 경우 무시 처리하고 계속 응답을 대기하면 된다.
		int GetFileCheckResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage, unsigned long long& nFileSize, std::string& szHashValue );


		/// @brief 대상과 연결된 Socket 을 통해 ftsd 로 Unlink 명령 전송.
		/// @param szFileName   [in] 원본 Source 파일명 (/stg/node0/186/abcde..)
		/// @param nFileSize    [in] 원본 파일의 크기 ( Byte 단위 )
		/// @param bForceUnlink [in] 강제 삭제 처리 여부 ( Defalult false )
		///                      false : 일반모드 - 해당 파일이 존재하고 Size 값이 동일할 경우에만 삭제처리.. 나머지는 오류로 처리.
		///                      true  : 강제모드 - 해당 파일이 존재하지 않거나.. Size 가 틀려도 강제로 삭제 처리.. 오류는 통신, 시스템 오류 발생시에만
		/// @return Unlink 요청 메시지 전송 성공시 true, 실패시 false 반환.
		bool SendFileUnlinkRequest(const std::string& szFileName, unsigned long long nFileSize, bool bForceUnlink = false );

		/// @brief File Unlink 요청에 대한 처리 결과를 ftsd 로 부터 수신한다. 
		/// @param nTimeout [in] 함수 호출에 대한 Blocking 을 방지하기 위한 Timeout 설정값. 단위( second )\n
		///<                     지정된 시간동안 응답을 수신하지 못한 경우 0 을 반환.
		/// @param bSuccess [out] File unlink 처리가 정상적으로 수행되었는지 여부 \n
		///<                      ftsd 상에서 오류가 발생한 경우 이 값은 false 가 되며 \n
		///<                      szErrorMessage 변수상에 오류내용이 저장됨. \n
		///<                      정상적으로 처리된 경우 true 가 저장되며 따로 수신하는 Data 는 없음. \n
		/// @param szErrorMessage [out] bSuccess == false 인 경우 발생된 오류메시지 정보를 저장
		/// @return -1 : Socket 통신 관련 오류 발생하여 ftsd 와 연결이 끊어진 경우 \n
		///<             => ftsd 와 연결이 끝어진것으로 판단하고 오류처리한다. \n
		///<
		///<         0 : 입력변수인 nTimeout 에 지정된 시간안에 ftsd 으로부터 처리 결과 정보를 수신하지 못한 경우. \n
		///<             이 기능은 본 함수 호출시 Blocking 발생을 막기 위한 기능으로서 \n
		///<             이 값이 반환된 경우 추가 다른 작업을 진행한 후 본 함수를 다시 호출하여 \n
		///<             응답을 대기할 수 있다. \n
		///<
		///<         1 : 파일 Unlink 처리에 대한 응답을 수신한 경우, Output 인자인 bSuccess 를 확인하여 처리 결과 확인
		///<             
		///<         2 : ftsd 으로 부터 Data 을 수신하였으나 File Unlink 요청에 대한 응답이 아닌 경우 \n
		///<             해당 정보는 본 클래스의 멤버변수 상에 내부적으로 저장된다. ( 단 Alive Packet 은 아님) \n
		///<             본 결과가 수신된 경우 무시 처리하고 계속 응답을 대기하면 된다.
		int GetFileUnlinkResult( int nTimeout, bool& bSuccess, std::string& szErrorMessage );

		
		/// @brief 연결된 Socket 통신을 이용하여 내부적으로 정의된 Alive Check 패킷 전송 \n
		///<       => 해당 패킷에 대한 처리는 내부적으로 처리되어 결과값을 확인할 필요는 없다.
		/// @return Socket 연결 해제 또는 전송 관련 오류 발생시 false, 전송 성공시에는 true 반환.
		bool SendAliveCheck(void);
		
		/// @brief Packet Header 정보를 Log 파일에 Logging 처리 ( Debug 처리를 위한 함수)
		void PrintHeaderToLog(void);


	protected:
		
		/// @brief Packet Header 부분의 수신 처리를 위한 함수. Alive Check 요청 패킷은 자동으로 무시처리함.
		/// @param timeout [in] 대기시간.
		/// @retrun 성공시 true, 오류 발생및 실패시 fasle 반환.
		bool GetPacketHeader(int timeout = DEFAULT_DATA_RECEIVE_TIMEOUT);

		/// @brief socket 에서 지정된 크기만큼의 데이터를 읽어 출력변수에 저장처리.
		/// @param size [in] read 할 데이터 크기
		/// @param value [out] 읽은 데이터를 저장할 string 변수
		/// @return On success return true, otherwise return false.
		bool GetPacketData( unsigned int& size, std::string& value );

		/// @brief socket 에서 지정된 크기만큼의 데이터를 읽어 내부 임시버퍼인 m_tempBuffer 에 저장처리.
		/// @param size [in] read 할 데이터 크기
		/// @return On success return true, otherwise return false.
		bool GetPacketData( unsigned int size );

		/// @brief pValue 에 저장된 데이터를 unsigned int 형으로 변환처리 및 Endian 변환
		unsigned int GetDataToUInt( BYTE * pValue, bool bConvertEndian = true );

		/// @brief pValue 에 저장된 데이터를 unsigned long long (64Byte) 형으로 변환처리.
		unsigned long long GetDataToUInt64( BYTE * pValue );


};

#endif /* __FTSD_SOCKET_CONTROL_H__ */

