#include "OwnCommandProcessorDefs.h"
#include <ICommandProcessor.h>
#include <IDiagRuntimeSystem.h>

#include <ISerializable.h>
#include <mutex>
#include <queue>

class NCOMMANDPROCESSOR_EXPORTS OwnCommandProcessor : public OpenTestSystem::OtxDiagManager::Common::ICommandProcessor
{
private:
	OpenTestSystem::OtxDiagManager::Common::IDiagRuntimeSystem* _diagRuntimeSystem;

	static std::mutex _mutex;
	/// <summary>
	/// A queue of command, this queue will be used when execute Async.
	/// </summary>
	static std::queue <OpenTestSystem::OtxDiagManager::Common::Command> _cmdQueue;
	/// <summary>
	/// True when executing commands in the queue.
	/// </summary>
	static bool _isExecuting;

	void AddCommandToQueue(const OpenTestSystem::OtxDiagManager::Common::Command& command);
	OpenTestSystem::OtxDiagManager::Common::Command PopCommandFromQueue();
	std::size_t GetCommandQueueSize();
public:
	OwnCommandProcessor();
	OwnCommandProcessor(OpenTestSystem::OtxDiagManager::Common::IDiagRuntimeSystem* drs);
	virtual ~OwnCommandProcessor();
	OpenTestSystem::OtxDiagManager::Common::Result* Execute(const OpenTestSystem::OtxDiagManager::Common::Command& command) override;
	OpenTestSystem::OtxDiagManager::Common::Result* ExecuteAsync(const OpenTestSystem::OtxDiagManager::Common::Command& command) override;
	void SetAsyncResultHandler(std::function<void(const OpenTestSystem::OtxDiagManager::Common::Result&)> handler) override;
	void SetExceptionHandler(std::function<void(const OpenTestSystem::OtxDiagManager::Common::Exception&)> handler) override;
};