#ifndef COMPARATOR_LIB_H
#define COMPARATOR_LIB_H

#include <functional>
#include <memory>
#include <string>
#include <user/comparatorApiDesc.h>
#include <loadableLib/loadableLibraryManager.h>
#include <spinscale/co/coQutex.h>
#include <spinscale/sharedResourceGroup.h>

namespace smo {
namespace comparator_lib {

class ComparatorApiManager;

class ComparatorLib
{
private:
	friend class ComparatorApiManager;

public:
	ComparatorLib(
		std::shared_ptr<loadable_lib::LoadableLibraryManager::LoadedSharedLibrary>
			_loadedSharedLibrary,
		SMO_GET_COMPARATOR_LIB_DESC_FN_TYPEDEF descFn)
	:	loadedSharedLibrary(std::move(_loadedSharedLibrary)),
		SMO_GET_COMPARATOR_LIB_DESC_FN_NAME(descFn),
		s("ComparatorLib-" + loadedSharedLibrary->libraryPath)
	{}

	void setComparatorLibDesc(const cologex::ComparatorLibDesc &desc)
	{
		if (!cologex::ComparatorLibDesc::sanityCheck(desc))
		{
			throw std::runtime_error(
				std::string(__func__) + ": Sanity check failed for comparator "
				"library descriptor in library '"
				+ loadedSharedLibrary->libraryPath + "'");
		}

		comparatorLibDesc = desc;
	}

	std::string stringify() const
	{
		std::string result = "Library Path: "
			+ loadedSharedLibrary->libraryPath + "\n";
		result += "Comparator Library Descriptor: "
			+ comparatorLibDesc.stringify();
		return result;
	}

public:
	std::shared_ptr<loadable_lib::LoadableLibraryManager::LoadedSharedLibrary>
		loadedSharedLibrary;

	std::function<SMO_GET_COMPARATOR_LIB_DESC_FN_TYPEDEF>
		SMO_GET_COMPARATOR_LIB_DESC_FN_NAME;

	cologex::ComparatorLibDesc comparatorLibDesc;

	struct ComparatorLibResources
	{};

	sscl::SharedResourceGroup<
		sscl::co::CoQutex, ComparatorLibResources> s;
};

} // namespace comparator_lib
} // namespace smo

#endif // COMPARATOR_LIB_H
