#pragma once
#include "data/command/ServiceCommands.h"
#include "data/command/FlashCommands.h"
#include "data/command/LoggingCommands.h"
#include "data/command/RemoteIOCommands.h"
#include "data/command/IOConfigCommands.h"
#include "data/command/SchedulerCommands.h"
#include "data/command/GccCommands.h"

namespace inertia
{

/** @brief Commands.
 *
 *  Class used to store a received command and to create a new command.
 */
struct INERTIA_API InertiaCommands
{
private:
	InertiaCommandPtr m_command;

public:
	/** Default Constructor.
	 *  Creates an empty command.
	 */
	InertiaCommands();

	/** Raw data Constructor.
	 *  Creates a command from raw binary data.
	 *  @param in input bytes
	 */
	InertiaCommands(std::vector<uint8_t> const& in);

	/** Constructor with string argument.
	 *  Creates a command from a string.
	 *  @param argString string with arguments
	 */
	InertiaCommands(std::wstring const& argString);

	/** Constructor taking an InertiaCommand.
	 *  @param command the command
	 */
	InertiaCommands(InertiaCommandPtr const& command);


	/** Return the associated command.
	 *  @return the command, or an empty pointer when not available.
	 */
	InertiaCommandPtr const GetCommand() const;

	/** Get the command group of the associated command.
	 *  @return the InertiaCommandGroups
	 */
	InertiaCommandGroups GetGroup() const;

	/** Get the type of he associated command, depends on the InertiaCommandGroups.
	 *  @return the command type, 0xFF (255) when unknown
	 */
	unsigned GetType() const;

	/** Get whether the command is a request or response.
	 *  @return true when the command is a response
	 */
	bool GetIsResponse() const;


	/** Get the bytes of the command.
	 *  @return a vector with the bytes
	 */
	std::vector<uint8_t> GetBytes() const;

#ifdef WITH_BOOST_PROGRAM_OPTIONS
	/** Get the possible command-line arguments for InertiaCommands.
	 *  Only available when \a WITH_BOOST_PROGRAM_OPTIONS is defined.
	 *  @return the option description
	 */
	static const po::options_description GetOptionDescription();
#endif

	/** Get a string representation of this InertiaCommands.
	 *  The string is compatible with GetOptionDescription() and InertiaCommands(std::wstring const&).
	 *  @return the string
	 */
	const std::wstring ToString() const;
};

}
