#pragma once

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

#include <pybind11/pybind11.h>

namespace py = pybind11;

/**
 * @brief Bind io::Stream class to python
 * @param m pybind The module to bind to
 */
void bind_stream(py::module &m) {
	using pybind11::operator""_a;

	py::class_<dv::io::Stream>(m, "Stream")
		.def(py::init<>())
		.def(py::init([](const int32_t id, const std::string &name, const std::string &sourceName,
						  const std::string &typeIdentifier) {
			return dv::io::Stream(id, name, sourceName, typeIdentifier);
		}),
			"id"_a, "name"_a, "sourceName"_a, "typeIdentifier"_a)
		.def("addMetadata", &dv::io::Stream::addMetadata, "name"_a, "value"_a,
			"Add metadata to the stream. If an entry already exists, it will be replaced with the new value.")
		.def("getMetadataValue", &dv::io::Stream::getMetadataValue, "name"_a, "Get a metadata value of the stream.")
		.def("setTypeDescription", &dv::io::Stream::setTypeDescription, "description"_a,
			"Set type description. This only sets type description metadata field.")
		.def("setModuleName", &dv::io::Stream::setModuleName, "moduleName"_a,
			"Set module name that originally produces the data. This only sets the original module name metadata "
			"field.")
		.def("setOutputName", &dv::io::Stream::setOutputName, "outputName"_a,
			"Set original output name. This only sets the original output name metadata field.")
		.def("setCompression", &dv::io::Stream::setCompression, "compression"_a,
			"Set compression metadata field for this stream. This only sets the metadata field of this stream.")
		.def("getTypeDescription", &dv::io::Stream::getTypeDescription, "Get type description.")
		.def("getModuleName", &dv::io::Stream::getModuleName, "Get module name.")
		.def("getOutputName", &dv::io::Stream::getOutputName, "Get output name.")
		.def("getCompression", &dv::io::Stream::getCompression, "Get compression type string.")
		.def("getResolution", &dv::io::Stream::getResolution, "Get resolution of this stream by parsing metadata.")
		.def("getSource", &dv::io::Stream::getSource,
			"Get source name (usually the camera name) from metadata of the stream.")
		.def("setResolution", &dv::io::Stream::setResolution, "resolution"_a, "Set the stream resolution.")
		.def("setSource", &dv::io::Stream::setSource, "source"_a, "Set the stream source, usually source camera name.")
		.def("setAttribute", &dv::io::Stream::setAttribute, "name"_a, "value"_a,
			"Set an attribute of this stream, if the attribute field does not exist, it will be created.")
		.def("getAttribute", &dv::io::Stream::getAttribute, "name"_a, "Get attribute value given it's name.")
		.def_readwrite("mId", &dv::io::Stream::mId)
		.def_readwrite("mName", &dv::io::Stream::mName)
		.def_readwrite("mTypeIdentifier", &dv::io::Stream::mTypeIdentifier)
		.def_readwrite("mType", &dv::io::Stream::mType)
		.def_static("EventStream", &dv::io::Stream::EventStream, "id"_a, "name"_a, "sourceName"_a, "resolution"_a)
		.def_static("FrameStream", &dv::io::Stream::FrameStream, "id"_a, "name"_a, "sourceName"_a, "resolution"_a)
		.def_static("IMUStream", &dv::io::Stream::IMUStream, "id"_a, "name"_a, "sourceName"_a)
		.def_static("TriggerStream", &dv::io::Stream::TriggerStream, "id"_a, "name"_a, "sourceName"_a);
}
