/**
 * @file CommonTrafficCaptureMessages.h
 * This header file defines simple data message used in communication with the 
 * TrafficCapture application.
 * @author Tomas Urban
 * @version 0.3
 * @date 23/07/2009
 */
#ifndef COMMON_TRAFFIC_CAPTURE_MESSAGES_H
#define COMMON_TRAFFIC_CAPTURE_MESSAGES_H
#include "TrafficCaptureMessageId.h"
#include "TrafficCaptureMessage.h"
#include <vector>

/**
 * This class describes a request containing command to start message capture.
 */
class StartCaptureRequest : public TrafficCaptureMessage
{
public:
	StartCaptureRequest() {}
	virtual ~StartCaptureRequest() {}
	virtual unsigned short GetId() const { return START_CAPTURE_REQ; }
};

/**
 * This class describes a reply to a request for starting message capture.
 */
class StartCaptureReply : public CommonReplyMessage
{
public:
	StartCaptureReply() {}
	virtual ~StartCaptureReply() {}
	virtual unsigned short GetId() const { return START_CAPTURE_REP; }
};

/**
 * This class describes a request containing command to stop message capture.
 */
class StopCaptureRequest : public TrafficCaptureMessage
{
public:
	StopCaptureRequest() {}
	virtual ~StopCaptureRequest() {}
	virtual unsigned short GetId() const { return STOP_CAPTURE_REQ; }
};

/**
 * This class describes a reply to a request for stopping message capture.
 */
class StopCaptureReply : public CommonReplyMessage
{
public:
	StopCaptureReply() {}
	virtual ~StopCaptureReply() {}
	virtual unsigned short GetId() const { return STOP_CAPTURE_REP; }
};

/**
 * This class describes a request used for initialization of traffic capture.
 */
class OpenDeviceRequest : public TrafficCaptureMessage
{
private:
	ECaptureType m_captureType;
	ECaptureMode m_captureMode;
	timeval m_timestamp;
	std::string m_sParams;
	std::string m_sCaptureFile;	
protected:
	virtual unsigned int CalculateDataLength();
	virtual void EncodePayload(unsigned int & nOffset);
	virtual bool DecodePayload(const char * pPayload, unsigned int nPayloadLength, unsigned int & nOffset);
public:
	OpenDeviceRequest();
	virtual ~OpenDeviceRequest() {}
	virtual unsigned short GetId() const { return OPEN_DEVICE_REQ; }
	/**
	 * Returns the requested capture type.
	 * @return Requested capture type
	 */
	ECaptureType GetCaptureType() const { return m_captureType; }
	/**
	 * Sets the requested capture type.
	 * @param captureType Requested capture type
	 */
	void SetCaptureType(ECaptureType captureType);
	/**
	 * Returns the requested capture mode.
	 * @return Requested capture mode
	 */
	ECaptureMode GetCaptureMode() const { return m_captureMode; }
	/**
	 * Sets the requested capture mode.
	 * @param captureMode Requested capture mode
	 */
	void SetCaptureMode(ECaptureMode captureMode);
	/**
	 * Returns the requested timestamp for time-based filter. If the returned value is equal to zero,
	 * no time-based filtering will occur.
	 * @return Timestamp for time-based filter
	 */
	struct timeval GetTimestamp() const { return m_timestamp; }
	/**
	 * Sets the timestamp for time-based filter. If the timestamp value is equal to zero, no
	 * time-based filtering will occur.
	 * @param timestamp Timestamp for time-based filter
	 */
	void SetTimestamp(struct timeval timestamp);
	/**
	 * Returns the parameter string used for initializing capturing device.
	 * @return Start-up parameters for capturing device
	 */
	std::string GetParameters() const { return m_sParams; }
	/**
	 * Sets the parameter string used for initializing capturing devices. The string format
	 * is device specific. Please check the documentation of supported devices for more details.
	 * @param sParams Start-up parameters for capturing device
	 */
	void SetParameters(const std::string & sParams);
	/**
	 * Returns the name of the file into which captured packets should be saved. Only devices
	 * using live capture are capable of saving data into files.
	 * @return Path to the capture file or empty string if no data should be saved
	 */
	std::string GetCaptureFile() const { return m_sCaptureFile; }
	/**
	 * Sets the name of the file into which captured packets should be saved. Only devices
	 * using live capture are capable of saving data into files.
	 * @param sFile Path to the capture file or empty string if no data should be saved
	 */
	void SetCaptureFile(const std::string & sFile);
};

/**
 * This class describes a reply to a traffic capture initialization request.
 */
class OpenDeviceReply : public TrafficCaptureMessage
{
private:	
	ECaptureInitResult m_result;
protected:
	virtual unsigned int CalculateDataLength();
	virtual void EncodePayload(unsigned int & nOffset);
	virtual bool DecodePayload(const char * pPayload, unsigned int nPayloadLength, unsigned int & nOffset);
public:
	OpenDeviceReply();
	virtual ~OpenDeviceReply() {}
	virtual unsigned short GetId() const { return OPEN_DEVICE_REP; }
	/**
	 * The method returns the result of the operation.
	 * @return Operation result
	 */
	ECaptureInitResult GetResult() const { return m_result; }
	/**
	 * The method sets the result of the operation. The default value is #ECaptureInit_Failed.
	 * @param result Operation result
	 */
	void SetResult(ECaptureInitResult result);
};

/**
 * This class describes a request used for setting a data filter.
 */
class SetFilterRequest : public TrafficCaptureMessage
{
private:
	std::string m_sFilter;
protected:
	virtual unsigned int CalculateDataLength();
	virtual void EncodePayload(unsigned int & nOffset);
	virtual bool DecodePayload(const char * pPayload, unsigned int nPayloadLength, unsigned int & nOffset);
public:
	SetFilterRequest() {}
	virtual ~SetFilterRequest() {}
	virtual unsigned short GetId() const { return SET_FILTER_REQ; }

	/**
	 * Gets requested filter parameters. If the string is empty, no filter shall be applied.
	 * @return Filter parameters
	 */
	std::string GetFilter() const { return m_sFilter; }
	/**
	 * Sets filter parameters. If no filtering should occur, the string shall be empty. The string format
	 * is device specific. Please check the documentation of supported devices for more details.
	 * @param sFilter Filter parameters
	 */
	void SetFilter(const std::string & sFilter);
};

/**
 * This class describes a reply to a filtering request.
 */
class SetFilterReply : public CommonReplyMessage
{
public:
	SetFilterReply() {}
	virtual ~SetFilterReply() {}
	virtual unsigned short GetId() const { return SET_FILTER_REP; }
};

/**
 * This class describes a merging request. This request is used for merging several pcap files
 * into one. If the operation is successful, the path to the file containing merged data is
 * returned by a subsequent response.
 */
class MergePcapFilesRequest : public TrafficCaptureMessage
{
private:
	std::string m_sMergePath, m_sMergecapPath;
	std::vector<std::string> m_vsMergeFiles;
protected:
	virtual unsigned int CalculateDataLength();
	virtual void EncodePayload(unsigned int & nOffset);
	virtual bool DecodePayload(const char * pPayload, unsigned int nPayloadLength, unsigned int & nOffset);
public:
	MergePcapFilesRequest() {}
	virtual ~MergePcapFilesRequest() {}
	virtual unsigned short GetId() const { return MERGE_FILES_REQ; }
	/**
	 * Sets the path to the directory where the mergecap tool is installed.
	 * @param sPath Path to mergecap installation directory
	 */
	void SetMergecapDirectory(const std::string & sPath);
	/**
	 * Returns path to the directory where the mergecap tool is installed.
	 * @return Path to mergecap installation directory
	 */
	std::string GetMergecapDirectory() {return m_sMergecapPath; }
	/**
	 * Sets the source data for the file merging operation.
	 * @param sMergePath Path to the directory containing files to merge. This directory
	 * is also used for storing the merged file.
	 * @param vsMergeFiles Vector containing files to merge
	 **/
	void SetMergeSource(const std::string & sMergePath, const std::vector<std::string> & vsMergeFiles);
	/**
	 * Returns the path to the directory containing files to merge. This directory
	 * will be also used for storing the merged file.
	 * @return Path of files to merge
	 */
	std::string GetMergePath() const { return m_sMergePath; }
	/**
	 * Returns a vector containing files to merge.
	 * @return Files to merge
	 */
	std::vector<std::string> GetFilesToMerge() const { return m_vsMergeFiles; }
};

/**
 * This class describes a reply to a merging request.
 */
class MergePcapFilesReply : public CommonReplyMessage
{
private:
	std::string m_sMergeFile;
protected:
	virtual unsigned int CalculateDataLength();
	virtual void EncodePayload(unsigned int & nOffset);
	virtual bool DecodePayload(const char * pPayload, unsigned int nPayloadLength, unsigned int & nOffset);
public:
	MergePcapFilesReply() {}
	virtual ~MergePcapFilesReply() {}
	virtual unsigned short GetId() const { return MERGE_FILES_REP; }
	/**
	 * Sets a path to the merge file. The path shall be set only in case of successful reply.
	 * @param sMergeFile Path to the merge file
	 */
	void SetMergeFile(const std::string & sMergeFile);
	/**
	 * Return a path to the merge file. In case of successful reply, this path shall be used as
	 * a parameter in a subsequent #OpenDeviceRequest for opening an offline pcap device. Refer to
	 * #OpenDeviceRequest::SetParameters() for more details.
	 * @return Path to the merge file
	 */
	std::string GetMergeFile() { return m_sMergeFile; }
};

#endif
