#ifndef OpenTestSystem_OtxDiagManager_Common_IDiagRuntimeSystem_H
#define OpenTestSystem_OtxDiagManager_Common_IDiagRuntimeSystem_H

#include "CommonDefs.h"
#include "CommonClasses.h"
#include <functional>

namespace OpenTestSystem
{
	namespace OtxDiagManager
	{
		/// <summary>
		/// Common classes for own implementations
		/// </summary>
		namespace Common
		{
			/// <summary>
			/// Interface which a DiagRuntimeSystem must be implemented
			/// </summary>
			class COMMON_EXPORTS IDiagRuntimeSystem
			{
			protected:
				IDiagRuntimeSystem() {};
			public:
				virtual ~IDiagRuntimeSystem() {};
				/// <summary>
				/// DiagRuntimeSystem executes the command synchronously
				/// </summary>
				/// <remarks>
				/// The DiagRuntimeSystem must execute the command synchronously and returns a result or an exception. The command contains a Google Protobuf data object, which is related according to OTX term or action (e.g. GetComChannel, ExecuteDiagService, ...). It contains all required parameter values.
				/// </remarks>
				/// <returns>Result of the execution</returns>
				virtual Common::Result * Execute(const Common::Command & command) = 0;
				/// <summary>
				/// DiagRuntimeSystem executes the command asynchronously
				/// </summary>
				/// <remarks>
				/// The DiagRuntimeSystem executes the command asynchronously and returns am empty result. The real result/exception when received will be given back via async result/exception handler, which is set in SetAsyncResultHandler/SetExceptionHandler. The command contains a Google Protobuf data object, which is related according to OTX term or action (e.g. GetComChannel, ExecuteDiagService, ...). It contains all required parameter values.
				/// </remarks>
				/// <returns>Result of the execution</returns>
				virtual Common::Result * ExecuteAsync(const Common::Command & command) = 0;
				/// <summary>
				/// Set an async result handler into DiagRuntimeSystem. 
				/// <remarks>
				/// At asynchonous execution, the DiagRuntimeSystem will call and give the result to the set handler when the execution finishes.
				/// </remarks>
				/// </summary>
				virtual void SetAsyncResultHandler(std::function<void(const Common::Result&)> handler) = 0;
				/// <summary>
				/// Set an exception handler into DiagRuntimeSystem. 
				/// <remarks>
				/// At asynchonous execution, the DiagRuntimeSystem will call and give the exception to the set handler when the execution has an exception.
				/// </remarks>
				/// </summary>
				virtual void SetExceptionHandler(std::function<void(const Common::Exception&)> handler) = 0;
				// ???
				// MCDSystem * GetMCDSystem();
			};
		}
	}
}
#endif // OpenTestSystem_OtxDiagManager_Common_IDiagRuntimeSystem_H
