#include <boostAsioLinkageFix.h>

#include <cameraManagerState.h>
#include <lcameraDev.h>
#include <stdexcept>

extern "C" {

void lcameraDev_main(
	const std::shared_ptr<sscl::ComponentThread>& componentThread)
{
	lcamera_dev::lcameraDevMain(componentThread);
}

void lcameraDev_exit(void)
{
	lcamera_dev::lcameraDevExit();
}

sscl::co::ViralNonPostingInvoker<lcamera_dev::LcameraDevGetOrCreateResult>
lcameraDev_getOrCreateDeviceCReq(const std::string& deviceSelector)
{
	lcamera_dev::LcameraDevState& state = lcamera_dev::getLcameraDevState();
	if (!state.isInitialized)
	{
		throw std::runtime_error(
			"lcameraDev_getOrCreateDeviceCReq: call lcameraDev_main first");
	}

	co_return co_await lcamera_dev::getOrCreateDeviceSessionCReq(deviceSelector);
}

sscl::co::ViralNonPostingInvoker<lcamera_dev::CameraIdentityRecord>
lcameraDev_resolveDeviceSelectorCReq(const std::string& deviceSelector)
{
	lcamera_dev::LcameraDevState& state = lcamera_dev::getLcameraDevState();
	if (!state.isInitialized)
	{
		throw std::runtime_error(
			"lcameraDev_resolveDeviceSelectorCReq: call lcameraDev_main first");
	}

	co_return co_await lcamera_dev::resolveDeviceSelectorCReq(deviceSelector);
}

sscl::co::ViralNonPostingInvoker<void>
lcameraDev_releaseDeviceCReq(
	const std::shared_ptr<lcamera_dev::CameraSession>& deviceSession)
{
	lcamera_dev::LcameraDevState& state = lcamera_dev::getLcameraDevState();
	if (!state.isInitialized)
	{
		throw std::runtime_error(
			"lcameraDev_releaseDeviceCReq: call lcameraDev_main first");
	}

	co_await lcamera_dev::releaseDeviceSessionCReq(deviceSession);
	co_return;
}

sscl::co::ViralNonPostingInvoker<std::vector<lcamera_dev::LcameraDevCameraInfo>>
lcameraDev_enumerateCamerasCReq(void)
{
	lcamera_dev::LcameraDevState& state = lcamera_dev::getLcameraDevState();
	if (!state.isInitialized)
	{
		throw std::runtime_error(
			"lcameraDev_enumerateCamerasCReq: call lcameraDev_main first");
	}

	co_return co_await lcamera_dev::enumerateCamerasCReq();
}

sscl::co::ViralNonPostingInvoker<lcamera_dev::LcameraDevConfiguredCameraMode>
lcameraDev_configureSessionModeCReq(
	const std::shared_ptr<lcamera_dev::CameraSession>& deviceSession,
	const lcamera_dev::LcameraDevCameraModeRequest& request)
{
	lcamera_dev::LcameraDevState& state = lcamera_dev::getLcameraDevState();
	if (!state.isInitialized)
	{
		throw std::runtime_error(
			"lcameraDev_configureSessionModeCReq: call lcameraDev_main "
			"first");
	}

	if (!deviceSession)
	{
		throw std::runtime_error(
			"lcameraDev_configureSessionModeCReq: deviceSession is null");
	}

	co_return co_await deviceSession->configureSessionModeCReq(request);
}

} // extern "C"
