#ifndef OpenTestSystem_OtxDiagManager_CommandProcessor_H
#define OpenTestSystem_OtxDiagManager_CommandProcessor_H

#include <memory>

#include <ICommandProcessor.h>
#include <ILog.h>

#include "CommandProcessorDefs.h"

using OpenTestSystem::OtxDiagManager::Common::IDiagRuntimeSystem;
using OpenTestSystem::OtxDiagManager::Common::Result;
using OpenTestSystem::OtxDiagManager::Common::Exception;
using OpenTestSystem::OtxDiagManager::Common::Command;
using OpenTestSystem::OtxDiagManager::Common::ILog;

namespace OpenTestSystem {
	namespace OtxDiagManager {
		/// <summary>
		/// Namespace containing all methods for the DiagManager CommandProcessor
		/// </summary>
		namespace CommandProcessor {

			struct CommandProcessorImpl;
			class CommandDispatcher;

			/// <summary>
			/// The interchangeable CommandProcessor contains methods to optimize the access to the diagnostic runtime system
			/// </summary>
			class CMD_PROCESSOR_EXPORTS CommandProcessor :
				public Common::ICommandProcessor
			{
			public:
				CommandProcessor();
				virtual ~CommandProcessor();

				Result* Execute(const Command& cmd) override;
				Result* ExecuteAsync(const Command& cmd) override;
				void SetAsyncResultHandler(std::function<void(const Result&)> handler) override;
				void SetExceptionHandler(std::function<void(const Exception&)> handler) override;
				/// <summary>
				/// Sets the diagnostic runtime system on the CommandProcessor
				/// </summary>
				/// <param name="runtimeSystem">Instance of the diagnostic runtime system</param>
				void SetRuntimeSystem(IDiagRuntimeSystem* runtimeSystem);
				void SetCommandDispatcher(std::unique_ptr<CommandDispatcher> dispatcher);
				
			protected:
				void HandleAsyncResult(const Result&);
				void HandleException(const Exception&);
				void UnregisterClient(int clientId);
				void Report(const std::string& type, const Command& cmd);
				void Log(ILog::Level level, const std::string& text);
				struct CommandProcessorImpl* _impl = nullptr;
			};
		}
	}
}

#endif // OpenTestSystem_OtxDiagManager_CommandProcessor_H