#pragma once

#include "ControlServices.h"

#include <memory>
#include <string>
class OpenGLComposite;
class RuntimeCoordinator;
class RuntimeEventDispatcher;
class RuntimeStore;

class RuntimeServices
{
public:
	using AppliedOscUpdate = ControlServices::AppliedOscUpdate;
	using CompletedOscCommit = ControlServices::CompletedOscCommit;

	explicit RuntimeServices(RuntimeEventDispatcher& runtimeEventDispatcher);
	~RuntimeServices();

	bool Start(OpenGLComposite& composite, RuntimeStore& runtimeStore, std::string& error);
	void BeginPolling(RuntimeCoordinator& runtimeCoordinator);
	void Stop();
	void BroadcastState();
	void RequestBroadcastState();
	bool QueueOscUpdate(const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& error);
	bool ApplyPendingOscUpdates(std::vector<AppliedOscUpdate>& appliedUpdates, std::string& error);
	bool QueueOscCommit(const std::string& routeKey, const std::string& layerKey, const std::string& parameterKey, const JsonValue& value, uint64_t generation, std::string& error);
	void ClearOscState();
	void ClearOscStateForLayerKey(const std::string& layerKey);
	void ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>& completedCommits);

private:
	std::unique_ptr<ControlServices> mControlServices;
};
