/***************************************************************************
    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 __FIMNGD_SOCKET_CONTROL_H__
#define __FIMNGD_SOCKET_CONTROL_H__

#include "BaseSocket.h"
#include "Protocol.h"
#include <stdint.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 CSocketControl : 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 생성자.
		CSocketControl();
		
		/// @brief 소멸자.
		~CSocketControl();


		/// @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 szRCID	  [in] 속한 RCID
		/// @param szFileName [in] 복제할 파일명 (/stg/node0/186/abcde..)
		/// @param nServiceID [in] 서비스 ID
		/// @param nFileSize  [in] 복제할 파일의 local 크기.
		/// @param nFDCount   [in] 복제할 원본 파일의 file description count
		bool SendIntenalCache(const std::string& szRCID, 
								const std::string& szFileName, 
								const std::string& szHostName, 
								uint32_t nServiceID,
								uint64_t nFileSize, 
								int nFDCount);

		bool SendAliveFhs(const std::string& szRCID, const std::string& szHostName);
		
		bool SendNetworkStat(const std::string& szRCID, const std::string& szHostName, std::vector<struct service_network_stat> &vecNetworkStat);
		bool GetNetworkStatResult(int timeout = DEFAULT_DATA_RECEIVE_TIMEOUT);

		/// @brief Packet Header 정보를 Log 파일에 Logging 처리 ( Debug 처리를 위한 함수)
		void PrintHeaderToLog(struct FileTransferPacketHeader packetHeader);

		bool GetAliveFhs(std::map<std::string, struct fhs_stat> &mapFhsStat);
	protected:
		
		/// @brief Packet Header 부분의 수신 처리를 위한 함수. Alive Check 요청 패킷은 자동으로 무시처리함.
		/// @param timeout [in] 대기시간.
		/// @retrun 성공시 true, 오류 발생및 실패시 fasle 반환.
		int GetPacketHeader(char stxCode, char typeCode, 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 /* __FIMNGD_SOCKET_CONTROL_H__ */

