/***************************************************************************
                client 에서 rc_syncd 와의 통신을 수행하기 위한 class
                -----------------------------------------
	begin      : 2014/09/15
	copyright  : (C) 2005 Solbox Inc.
	author     : Storage Dev Team
	email      : storage.sd@solbox.com
	version    : 3.4

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

#ifndef __RC_SYNCD_CLIENT_SOCKET_H__
#define __RC_SYNCD_CLIENT_SOCKET_H__


#include "BaseSocket.h"
#include "RcSyncdProtocol.h"
#include "RcSyncdRequestData.h"

#include <string>


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


#define DEFAULT_SOCKET_TEMP_BUFFER_SIZE		1024	// Socket 관련 data 송수신시 사용할 임시버퍼 크기.


// CRcSyncdClientSocket
// 내부 또는 외부 모듈에서 rc_syncd 와 통신 수행시...
// 함수 수준의 단순 Interface 지원 목적을 위한 통신 관련 처리 class
class CRcSyncdClientSocket : public CBaseSocket
{
	public:

		// 생성자
		CRcSyncdClientSocket();

		// 소멸자
		~CRcSyncdClientSocket();


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

		// rc_syncd 로 sync 명령 전달.
		// - CReqMasterData class 멤버변수 수정시 본 함수 수정 필요함.		
		// @param request      [in] 요청 정보 저장 객체		
		// @return true  요청 성공시
		//         fasle 유효하지 않은 인자값 또는 전송 실패시
		bool SendSyncRequest( CReqMasterData& request );
		
		
		// rc_syncd 로 부터 sync 요청에 대한 결과 수신.
		// @param nTimeout       [in] 함수 호출에 대한 Blocking 을 방지하기 위한 Timeout 설정값. 단위( second )
		//                            지정된 시간동안 응답을 수신하지 못한 경우 0 을 반환.
		// @param bSuccess       [out] 성공 여부
		// @param strMessage     [out] rc_syncd 로부터 처리 관련 수신된 메시지
		// @return
		//         -1  : rc_syncd 와 통신이 끊어진 경우.
		//          0  : rc_syncd 로 부터 응답을 아직 수신하지 못한 경우.. 
		//               - 함수 blocking 방지 목적
		//               => AliveCheck 등의 작업 후 다시 응답 대기하면 된다.
		//          1  : Sync 요청에 대한 응답을 수신한 경우
		//          2  : Sync 요청에 대한 응답이 아닌 경우.. 
		//               => 무시 처리하고 계속 응답을 대기하면 된다.
		int GetSyncResult( int nTimeout, bool& bSuccess, std::string& strMessage );
		

		// Alive Check 를 위한 패킷 전송 => 해당 패킷에 대한 응답은 필요없으므로 수신시 자동 무시처리됨.
		// @return 전송 성공시 true, 실패시 false 반환.
		bool SendAliveCheck( void );
		
		// Packet Header 정보를 Log 파일에 Logging 처리
		// - 통신 오류 발생시 로깅을 통한 디버깅 지원 목적
		void PrintHeaderToLog( void );


	private:
		
		// Packet Header 변수
		struct RcSyncdPacketHeader m_packetHeader;

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

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

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

	protected:


		// Packet 정보 중 String 정보를 전송하기 위한 함수.
		bool SendString( const std::string& strData );

		// 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 );

		// socket 에서 지정된 크기만큼의 데이터를 읽어 내부 임시버퍼인 m_tempBuffer 에 저장처리.
		// @param size [in] read 할 데이터 크기
		// @return On success return true, otherwise return false.
		bool GetPacketData( unsigned int size );
		
		// pValue 에 저장된 데이터를 unsigned int 형으로 변환처리 및 Endian 변환
		unsigned int GetDataToUInt( BYTE * pValue, bool bConvertEndian = true );

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

};

#endif /* __RC_SYNCD_CLIENT_SOCKET_H__ */

