#include <boostAsioLinkageFix.h>

#include <lcameraDev.h>
#include <probeRunner.h>
#include <iostream>
#include <spinscale/co/nonViralTaskNursery.h>

namespace {

sscl::co::NonViralNonPostingInvoker listCamerasCInd(
	std::exception_ptr& exceptionStorage,
	std::function<void()> callerLambda)
{
	(void)exceptionStorage;
	(void)callerLambda;

	const std::vector<lcamera_dev::LcameraDevCameraInfo> cameras =
		co_await lcameraDev_enumerateCamerasCReq();

	std::cout << "lcameraDev: found " << cameras.size() << " camera(s)\n";

	for (size_t i = 0; i < cameras.size(); ++i)
	{
		const lcamera_dev::LcameraDevCameraInfo& info = cameras[i];

		std::cout << "  [" << i << "] id=" << info.id;
		if (!info.model.empty()) {
			std::cout << " model=" << info.model;
		}
		if (!info.location.empty()) {
			std::cout << " location=" << info.location;
		}
		std::cout << '\n';
	}

	co_return;
}

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

	sscl::co::NonViralTaskNursery nursery;
	nursery.openAdmission();
	nursery.launch(
		[](sscl::co::NonViralTaskNursery::Slot::Lease& lease)
		{
			return listCamerasCInd(
				lease.getExceptionStorage(),
				lease.getCallerLambda());
		});
	nursery.closeAdmission();
	nursery.syncAwaitAllSettlements(componentThread->getIoContext());

	lcameraDev_exit();
}

} // namespace

int main()
{
	try {
		lcamera_dev_probe::runOnComponentThread(runListCameras);
		return 0;
	}
	catch (const std::exception& exc) {
		std::cerr << "lcameraDev_list_cameras: " << exc.what() << '\n';
		return 1;
	}
}
