#ifndef OpenTestSystem_OtxDiagManager_Common_Exception_H
#define OpenTestSystem_OtxDiagManager_Common_Exception_H

#include "Command.h"
#include "CommonDefs.h"

namespace OpenTestSystem
{
	namespace OtxDiagManager
	{
		namespace Common
		{
			enum ExceptionTypesPb : int;
			class CommandDataPb;
			class COMMON_EXPORTS Exception : public ParameterContainer, public std::exception
			{
			public:
				Exception(const Command& command);
				virtual ~Exception();

				// Data from command
				
				/// <summary>
				/// Get Client Id in Command.
				/// </summary>
				/// <returns>Client Id.</returns>
				int GetClientId() const;	// only used on server side
				/// <summary>
				/// Get unique Command Id.
				/// </summary>
				/// <returns>Unique Command Id.</returns>
				int GetCommandId() const;	// this is the unique id of command
				/// <summary>
				/// Set Command Type.
				/// </summary>
				/// <remarks>
				/// E.g: UserCommand = 0 (default), GetComChannel = 1, CreateDiagService = 2, ...
				/// </remarks>
				/// <param name="commandType">Command Type.</param>
				int GetCommandType() const; // this is command type, e.g: UserCommand = 0 (default), GetComChannel = 1, CreateDiagService = 2, ...
				/// <summary>
				/// Get Command Name in Command.
				/// </summary>
				/// <returns>Command Name.</returns>
				std::string GetCommandName() const;
				/// <summary>
				/// Set exception data into result.
				/// </summary>
				/// <param name="errorcode">Exception error code.</param>
				/// <param name="type">Exception type. E.g: UnknownException = 0; InvalidReferenceException = 1; OutOfBoundsException = 2; TypeMismatchException = 3; ...</param>
				/// <param name="message">Exception message.</param>
				void SetExceptionData(int errorcode, ExceptionTypesPb type, const std::string& message);
				/// <summary>
				/// Get exception data from result.
				/// </summary>
				/// <param name="errorcode">Exception error code.</param>
				/// <param name="type">Exception type. E.g: UnknownException = 0; InvalidReferenceException = 1; OutOfBoundsException = 2; TypeMismatchException = 3; ...</param>
				/// <param name="message">Exception message.</param>
				void GetExceptionData(int& errorcode, ExceptionTypesPb& type, std::string& message);
				/// <summary>
				/// Serialize the internal Google Protobuf data object in the output string.
				/// </summary>
				/// <param name="output">Output string.</param>	
				void Serialize(std::string* output) const override;
				/// <summary>
				/// Deserialize the data string into the internal Google Protobuf data object.
				/// </summary>
				/// <param name="data">Output string.</param>
				void Deserialize(const std::string& data) override;
			private:
				int _clientId;
				CommandDataPb* _data;
			};
		};
	}
}
#endif // OpenTestSystem_OtxDiagManager_Common_Exception_H
