/***************************************************************************
                client 에서 cc_collectd 와의 통신을 수행하기 위한 class
                -----------------------------------------
	begin      : 2014/09/29
	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 __CC_COLLECTD_CLIENT_SOCKET_H__
#define __CC_COLLECTD_CLIENT_SOCKET_H__

#include "BaseSocket.h"
#include "CcCollectdProtocol.h"

#include <string>
#include <stdint.h>


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


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


// CCcCollectdClientSocket
// cc_collectd 모듈과 통신 수행 관련 Interface 지원 목적을 위한 통신 관련 처리 class
class CCcCollectdClientSocket : public CBaseSocket
{

	public:

		// 생성자
		CCcCollectdClientSocket();
		
		// 소멸자
		~CCcCollectdClientSocket();
		
	
		// 전달받은 Target 으로 Socket 접속을 수행
		// @param szTarget [in] 접속 대상 Host name 또는 IP
		// @param nPort	[in] 접속 Port
		// @return 접속 성공시 true, 실패시 false 반환. ( 오류 내역은 로깅처리됨.)
		bool ConnectTarget( const std::string& szTarget, int nPort );
		
		// cc_collect 로 File 존재 여부 확인
		// @param strProcessName  [in] 프로세스 명, 저장시 프로세스 명에 따른 폴더 생성 후 파일 수신, 저장 처리함. 
		//                             생략 가능하지만.. '/' 문자가 포함되서는 안됨.
		//
		// @param strFileName     [in] 저장 파일명
		//                             a.log 같은 단순 형식 사용, 
		//                             /a/b.log 같은 경로 정보 포함시 오류 발생.
		//		
		// @param nFileSize       [out] 해당 파일이 존재할 경우 파일의 크기
		//                              만약 해당 파일이 존재하지 않을 경우.. 크기는 0 
		//
		// @param strErrorMessage [out] 수신된 오류 메시지 저장
		// @return
		//        성공시 true, 파일 크기는  nFileSize 항목 참고.
		//        오류 발생시 false, 오류 내역은 strMessage 항목 참고
		bool CheckFile( const std::string strProcessName, const std::string strFileName
					   , unsigned long long& uFileSize
					   , std::string& strErrorMessage );
		

		// cc_collect 로 File 저장 목적으로 전송 
		// @param strProcessName  [in] 프로세스 명, 저장시 프로세스 명에 따른 폴더 생성 후 파일 수신, 저장 처리함. 
		//                             생략 가능하지만.. '/' 문자가 포함되서는 안됨.
		//
		// @param strFileName     [in] 저장 파일명
		//                             a.log 같은 단순 형식 사용, 
		//                             /a/b.log 같은 경로 정보 포함시 오류 발생.
		//
		// @param fd              [in] 전송할 파일에 대한 descriter
		// @param nFileSize       [in] 전송할 파일의 크기
		//                             0 파일 전송 가능.
		// @param strMessage      [out] 수신된 메시지 저장 (정상, 오류 모두 메시지 수신 가능)
		// @return
		//        저장 성공시 true
		//        실패 발생시 false, 오류 내역은 strMessage 항목 참고
		bool SendFile( const std::string strProcessName, const std::string strFileName
					   , const int& fd, const unsigned long long& uFileSize
					   , std::string& strMessage );
	

	private:
		
		// cc_collect 로부터 available size 정보를 요청, 결과를 수신처리한다.
		bool GetAvailableSize( unsigned long long& uSize );


	private:
	
		// Packet Header 정보를 Log 파일에 Logging 처리
		void PrintHeaderToLog();

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

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

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

		// Linux 5.4 의 경우 unsigned long long 의 byteorder 변환함수 제공 안함.
		// Linux 6.X, FreeBSD 에서는 be64toh 등의 함수 제공
		// - Liunx 5.X 장비 지원해야 하므로...  64bit 변환 함수 개발하여 사용.
		// - 기존 htonl 등의 함수와의 혼동을 피하기 위해 함수명은 C Style 로 구성.
		uint64_t do_htonll( uint64_t hostlonglong );
		uint64_t do_ntohll( uint64_t netlonglong );


	private:
		
		// Packet Header 변수
		struct CcCollectdPacketHeader 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];

};

#endif /* __CC_COLLECTD_CLIENT_SOCKET_H__ */

