/**
 * @file CommonTrafficCaptureMessages.cpp
 * @author Tomas Urban
 * @version 0.3
 * @date 23/07/2009
 */
#include "CommonTrafficCaptureMessages.h"

OpenDeviceRequest::OpenDeviceRequest() :
	m_captureType(ECaptureType_PCAP),
	m_captureMode(ECaptureMode_Live)
{
	m_timestamp.tv_sec = 0;
	m_timestamp.tv_usec = 0;
}

void OpenDeviceRequest::SetCaptureType(ECaptureType captureType)
{
	DisposeEncodedData();
	m_captureType = captureType;
}

void OpenDeviceRequest::SetCaptureMode(ECaptureMode captureMode)
{
	DisposeEncodedData();
	m_captureMode = captureMode;
}

void OpenDeviceRequest::SetTimestamp(struct timeval timestamp)
{
	DisposeEncodedData();
	m_timestamp = timestamp;
}

void OpenDeviceRequest::SetParameters(const std::string & sParams)
{
	DisposeEncodedData();
	m_sParams = sParams;
}

void OpenDeviceRequest::SetCaptureFile(const std::string & sFile)
{
	DisposeEncodedData();
	m_sCaptureFile = sFile;
}

unsigned int OpenDeviceRequest::CalculateDataLength()
{
	return TrafficCaptureMessage::CalculateDataLength() +
		1 + // capture type
		1 + // capture mode
		TIME_SIZE + // timestamp is forced to 32bits
		CalculateStringLength(m_sParams) + // parameters
		CalculateStringLength(m_sCaptureFile); // file name for saving captured data
}

void OpenDeviceRequest::EncodePayload(unsigned int & nOffset)
{
	TrafficCaptureMessage::EncodePayload(nOffset);
	EncodeUChar(static_cast<unsigned char>(m_captureType), nOffset);
	EncodeUChar(static_cast<unsigned char>(m_captureMode), nOffset);
	EncodeTime(m_timestamp, nOffset);	
	EncodeString(m_sParams, nOffset);
	EncodeString(m_sCaptureFile, nOffset);
}

bool OpenDeviceRequest::DecodePayload(const char * pPayload, unsigned int nPayloadLength, 
									  unsigned int & nOffset)
{
	if (!TrafficCaptureMessage::DecodePayload(pPayload, nPayloadLength, nOffset))
		return false;
	unsigned char c;
	if (!DecodeUChar(c, pPayload, nPayloadLength, nOffset))
		return false;
	m_captureType = static_cast<ECaptureType>(c);
	if (!DecodeUChar(c, pPayload, nPayloadLength, nOffset))
		return false;
	m_captureMode = static_cast<ECaptureMode>(c);
	if (!DecodeTime(m_timestamp, pPayload, nPayloadLength, nOffset))
		return false;
	if (!DecodeString(m_sParams, pPayload, nPayloadLength, nOffset))
		return false;
	if (!DecodeString(m_sCaptureFile, pPayload, nPayloadLength, nOffset))
		return false;
	return true;
}

OpenDeviceReply::OpenDeviceReply() :
	m_result(ECaptureInit_Failed)
{
}

void OpenDeviceReply::SetResult(ECaptureInitResult result)
{
	DisposeEncodedData();
	m_result = result;
}

unsigned int OpenDeviceReply::CalculateDataLength()
{
	return TrafficCaptureMessage::CalculateDataLength() +
		1; // operation result
}

void OpenDeviceReply::EncodePayload(unsigned int & nOffset)
{
	TrafficCaptureMessage::EncodePayload(nOffset);
	EncodeUChar(static_cast<unsigned char>(m_result), nOffset);
}

bool OpenDeviceReply::DecodePayload(const char * pPayload, unsigned int nPayloadLength, 
									  unsigned int & nOffset)
{
	if (!TrafficCaptureMessage::DecodePayload(pPayload, nPayloadLength, nOffset))
		return false;
	unsigned char c;
	if (!DecodeUChar(c, pPayload, nPayloadLength, nOffset))
		return false;
	m_result = static_cast<ECaptureInitResult>(c);
	return true;
}


void SetFilterRequest::SetFilter(const std::string & sFilter)
{
	DisposeEncodedData();
	m_sFilter = sFilter;
}

unsigned int SetFilterRequest::CalculateDataLength()
{
	return TrafficCaptureMessage::CalculateDataLength() +
		CalculateStringLength(m_sFilter);
}

void SetFilterRequest::EncodePayload(unsigned int & nOffset)
{
	TrafficCaptureMessage::EncodePayload(nOffset);
	EncodeString(m_sFilter, nOffset);
}

bool SetFilterRequest::DecodePayload(const char * pPayload, unsigned int nPayloadLength, 
									  unsigned int & nOffset)
{
	if (!TrafficCaptureMessage::DecodePayload(pPayload, nPayloadLength, nOffset))
		return false;
	if (!DecodeString(m_sFilter, pPayload, nPayloadLength, nOffset))
		return false;
	return true;
}

void MergePcapFilesRequest::SetMergeSource(const std::string & sMergePath, 
										   const std::vector<std::string> & vsMergeFiles)
{
	DisposeEncodedData();
	m_sMergePath = sMergePath;
	m_vsMergeFiles = vsMergeFiles;
}


void MergePcapFilesRequest::SetMergecapDirectory(const std::string & sPath)
{
	DisposeEncodedData();
	m_sMergecapPath = sPath;
}

unsigned int MergePcapFilesRequest::CalculateDataLength()
{
	int nLen = TrafficCaptureMessage::CalculateDataLength() +
		CalculateStringLength(m_sMergecapPath) +
		CalculateStringLength(m_sMergePath) +
		sizeof(unsigned int);
	int nCount = m_vsMergeFiles.size();
	for (int i = 0; i < nCount; ++i)
		nLen += CalculateStringLength(m_vsMergeFiles[i]);
	return nLen;
}

void MergePcapFilesRequest::EncodePayload(unsigned int & nOffset)
{
	TrafficCaptureMessage::EncodePayload(nOffset);
	EncodeString(m_sMergecapPath, nOffset);
	EncodeString(m_sMergePath, nOffset);
	unsigned int nCount = m_vsMergeFiles.size();
	EncodeUInt(nCount, nOffset);
	for (unsigned int i = 0; i < nCount; ++i)
		EncodeString(m_vsMergeFiles[i], nOffset);
}

bool MergePcapFilesRequest::DecodePayload(const char * pPayload, unsigned int nPayloadLength, 
									  unsigned int & nOffset)
{
	if (!TrafficCaptureMessage::DecodePayload(pPayload, nPayloadLength, nOffset))
		return false;
	if (!DecodeString(m_sMergecapPath, pPayload, nPayloadLength, nOffset))
		return false;
	if (!DecodeString(m_sMergePath, pPayload, nPayloadLength, nOffset))
		return false;
	unsigned int nCount = 0;
	if (!DecodeUInt(nCount, pPayload, nPayloadLength, nOffset))
		return false;
	m_vsMergeFiles.clear();
	for (unsigned int i = 0; i < nCount; ++i)
	{
		m_vsMergeFiles.push_back("");
		if (!DecodeString(m_vsMergeFiles[i], pPayload, nPayloadLength, nOffset))
			return false;
	}
	return true;
}

void MergePcapFilesReply::SetMergeFile(const std::string & sMergeFile)
{
	DisposeEncodedData();
	m_sMergeFile = sMergeFile;
}

unsigned int MergePcapFilesReply::CalculateDataLength()
{
	int nLen =  TrafficCaptureMessage::CalculateDataLength();
	if (GetResult())
		nLen += CalculateStringLength(m_sMergeFile);
	return nLen;
}

void MergePcapFilesReply::EncodePayload(unsigned int & nOffset)
{
	TrafficCaptureMessage::EncodePayload(nOffset);
	if (GetResult())
		EncodeString(m_sMergeFile, nOffset);
}

bool MergePcapFilesReply::DecodePayload(const char * pPayload, unsigned int nPayloadLength, 
									  unsigned int & nOffset)
{
	if (!TrafficCaptureMessage::DecodePayload(pPayload, nPayloadLength, nOffset))
		return false;
	if (GetResult() && !DecodeString(m_sMergeFile, pPayload, nPayloadLength, nOffset))
		return false;
	return true;
}
