#pragma once

#include "../../../include/dv-processing/io/input_base.hpp"

#include <pybind11/pybind11.h>

namespace py = pybind11;

/**
 * @brief Bind discoverDevices class to python
 * @param m pybind The module to bind to
 */
void bind_input_base(py::module &m) {
	py::class_<dv::io::InputBase> inputBase(m, "InputBase", "Base class for all inputs.");

	inputBase.def("getNextEventBatch", &dv::io::InputBase::getNextEventBatch, "Parse and retrieve next event batch.")
		.def("getNextFrame", &dv::io::InputBase::getNextFrame, "Parse and retrieve next frame.")
		.def("getNextImuBatch", &dv::io::InputBase::getNextImuBatch, "Parse and retrieve next IMU data batch.")
		.def("getNextTriggerBatch", &dv::io::InputBase::getNextTriggerBatch,
			"Parse and retrieve next trigger data batch.")
		.def("getEventResolution", &dv::io::InputBase::getEventResolution,
			"Get the resolution of the event data stream if it is available.")
		.def("getFrameResolution", &dv::io::InputBase::getFrameResolution,
			"Get the resolution of the frame data stream if it is available.")
		.def("isStreamAvailable", &dv::io::InputBase::isStreamAvailable, py::arg("streamName"),
			"Check whether a stream with given name is available.")
		.def("isEventStreamAvailable", &dv::io::InputBase::isEventStreamAvailable,
			"Check whether event stream is available.")
		.def("isFrameStreamAvailable", &dv::io::InputBase::isFrameStreamAvailable,
			"Checks whether frame data stream is present in the file.")
		.def("isImuStreamAvailable", &dv::io::InputBase::isImuStreamAvailable, "Check whether device outputs IMU data.")
		.def("isTriggerStreamAvailable", &dv::io::InputBase::isTriggerStreamAvailable,
			"Check whether device outputs trigger data.")
		.def("getCameraName", &dv::io::InputBase::getCameraName,
			"Get camera name, which is a combination of the camera model and the serial number.")
		.def(
			"isRunning",
			[](const dv::io::InputBase &self) -> bool {
				return self.isRunning();
			},
			"Check whether any input data streams have terminated. For a live camera this should check if the device "
			"is still connected and functioning, while for a recording file this should check if any of the data "
			"streams have reached end-of-file (EOF). For a network input, this indicates the network stream is still "
			"connected.")
		.def(
			"isRunning",
			[](const dv::io::InputBase &self, const std::string_view streamName) -> bool {
				return self.isRunning(streamName);
			},
			py::arg("streamName"), "Check whether the input data stream with the specified name is still active.")
		.def("isRunningAny", &dv::io::InputBase::isRunningAny,
			"Check whether any input data streams are still available. For a live camera this should check if the "
			"device is still connected and functioning and at least one data stream is active (different than "
			"isRunning()), while for recording file this should check if any of the data streams have not yet reached "
			"end-of-file (EOF) and are still readable. For a network input, this indicates the network stream is still "
			"connected.");
}
