#pragma once

#include "../../../include/dv-processing/io/camera/discovery.hpp"

#include <pybind11/pybind11.h>

namespace py = pybind11;

/**
 * @brief Bind discoverDevices class to python
 * @param m pybind The module to bind to
 */
void bind_discovery(py::module &m) {
	static dv::io::camera::USBDevice::loggerCallbackType DEFAULT_CLI_LOGGER
		= [](const dv::io::camera::USBDevice::LogLevel level, const std::string_view deviceName,
			  const std::string_view message) {
			  std::cerr << fmt::format("[{}] {}: {}", level, deviceName, message) << std::endl;
		  };

	m.def(
		"discover",
		[]() {
			return dv::io::camera::discover(DEFAULT_CLI_LOGGER);
		},
		"Discover all compatible cameras connected to this system.");

	m.def(
		"open",
		[](const dv::io::camera::USBDevice::DeviceDescriptor &descriptor,
			const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return dv::io::camera::open(descriptor, DEFAULT_CLI_LOGGER, deviceLogLevel);
		},
		py::arg("descriptor"), py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
		"Open the device with the specified descriptor structure.");
	m.def(
		"open",
		[](const std::string_view serialNumber, const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return dv::io::camera::open(serialNumber, DEFAULT_CLI_LOGGER, deviceLogLevel);
		},
		py::arg("serialNumber"), py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
		"Open the device with the specified serial number.");
	m.def(
		"open",
		[](const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return dv::io::camera::open(DEFAULT_CLI_LOGGER, deviceLogLevel);
		},
		py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
		"Open the first device that can be found.");

	m.def(
		"openSync",
		[](const dv::io::camera::USBDevice::DeviceDescriptor &descriptor,
			const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return dv::io::camera::openSync(descriptor, DEFAULT_CLI_LOGGER, deviceLogLevel);
		},
		py::arg("descriptor"), py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
		"Open the device with the specified descriptor structure. Device must support clock synchronization.");
	m.def(
		"openSync",
		[](const std::string_view serialNumber, const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return dv::io::camera::openSync(serialNumber, DEFAULT_CLI_LOGGER, deviceLogLevel);
		},
		py::arg("serialNumber"), py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
		"Open the device with the specified serial number. Device must support clock synchronization.");
}
