#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/native_enum.h>

#include "icsneo/api/event.h"

namespace icsneo {

void init_event(pybind11::module_& m) {
	pybind11::classh<APIEvent> apiEvent(m, "APIEvent");
	pybind11::native_enum<APIEvent::Type>(apiEvent, "Type", "enum.IntEnum")
		.value("Any", APIEvent::Type::Any)
		.value("InvalidNeoDevice", APIEvent::Type::InvalidNeoDevice)
		.value("RequiredParameterNull", APIEvent::Type::RequiredParameterNull)
		.value("BufferInsufficient", APIEvent::Type::BufferInsufficient)
		.value("OutputTruncated", APIEvent::Type::OutputTruncated)
		.value("ParameterOutOfRange", APIEvent::Type::ParameterOutOfRange)
		.value("DeviceCurrentlyOpen", APIEvent::Type::DeviceCurrentlyOpen)
		.value("DeviceCurrentlyClosed", APIEvent::Type::DeviceCurrentlyClosed)
		.value("DeviceCurrentlyOnline", APIEvent::Type::DeviceCurrentlyOnline)
		.value("DeviceCurrentlyOffline", APIEvent::Type::DeviceCurrentlyOffline)
		.value("DeviceCurrentlyPolling", APIEvent::Type::DeviceCurrentlyPolling)
		.value("DeviceNotCurrentlyPolling", APIEvent::Type::DeviceNotCurrentlyPolling)
		.value("UnsupportedTXNetwork", APIEvent::Type::UnsupportedTXNetwork)
		.value("MessageMaxLengthExceeded", APIEvent::Type::MessageMaxLengthExceeded)
		.value("ValueNotYetPresent", APIEvent::Type::ValueNotYetPresent)
		.value("Timeout", APIEvent::Type::Timeout)
		.value("WiVINotSupported", APIEvent::Type::WiVINotSupported)
		.value("RestrictedEntryFlag", APIEvent::Type::RestrictedEntryFlag)
		.value("NotSupported", APIEvent::Type::NotSupported)
		.value("FixedPointOverflow", APIEvent::Type::FixedPointOverflow)
		.value("FixedPointPrecision", APIEvent::Type::FixedPointPrecision)
		.value("SyscallError", APIEvent::Type::SyscallError)
		.value("PollingMessageOverflow", APIEvent::Type::PollingMessageOverflow)
		.value("NoSerialNumber", APIEvent::Type::NoSerialNumber)
		.value("IncorrectSerialNumber", APIEvent::Type::IncorrectSerialNumber)
		.value("SettingsReadError", APIEvent::Type::SettingsReadError)
		.value("SettingsVersionError", APIEvent::Type::SettingsVersionError)
		.value("SettingsLengthError", APIEvent::Type::SettingsLengthError)
		.value("SettingsChecksumError", APIEvent::Type::SettingsChecksumError)
		.value("SettingsNotAvailable", APIEvent::Type::SettingsNotAvailable)
		.value("SettingsReadOnly", APIEvent::Type::SettingsReadOnly)
		.value("CANSettingsNotAvailable", APIEvent::Type::CANSettingsNotAvailable)
		.value("CANFDSettingsNotAvailable", APIEvent::Type::CANFDSettingsNotAvailable)
		.value("LSFTCANSettingsNotAvailable", APIEvent::Type::LSFTCANSettingsNotAvailable)
		.value("SWCANSettingsNotAvailable", APIEvent::Type::SWCANSettingsNotAvailable)
		.value("BaudrateNotFound", APIEvent::Type::BaudrateNotFound)
		.value("UnexpectedNetworkType", APIEvent::Type::UnexpectedNetworkType)
		.value("DeviceFirmwareOutOfDate", APIEvent::Type::DeviceFirmwareOutOfDate)
		.value("SettingsStructureMismatch", APIEvent::Type::SettingsStructureMismatch)
		.value("SettingsStructureTruncated", APIEvent::Type::SettingsStructureTruncated)
		.value("NoDeviceResponse", APIEvent::Type::NoDeviceResponse)
		.value("MessageFormattingError", APIEvent::Type::MessageFormattingError)
		.value("CANFDNotSupported", APIEvent::Type::CANFDNotSupported)
		.value("RTRNotSupported", APIEvent::Type::RTRNotSupported)
		.value("DeviceDisconnected", APIEvent::Type::DeviceDisconnected)
		.value("OnlineNotSupported", APIEvent::Type::OnlineNotSupported)
		.value("TerminationNotSupportedDevice", APIEvent::Type::TerminationNotSupportedDevice)
		.value("TerminationNotSupportedNetwork", APIEvent::Type::TerminationNotSupportedNetwork)
		.value("AnotherInTerminationGroupEnabled", APIEvent::Type::AnotherInTerminationGroupEnabled)
		.value("NoSerialNumberFW", APIEvent::Type::NoSerialNumberFW)
		.value("NoSerialNumber12V", APIEvent::Type::NoSerialNumber12V)
		.value("NoSerialNumberFW12V", APIEvent::Type::NoSerialNumberFW12V)
		.value("EthPhyRegisterControlNotAvailable", APIEvent::Type::EthPhyRegisterControlNotAvailable)
		.value("DiskNotSupported", APIEvent::Type::DiskNotSupported)
		.value("EOFReached", APIEvent::Type::EOFReached)
		.value("SettingsDefaultsUsed", APIEvent::Type::SettingsDefaultsUsed)
		.value("AtomicOperationRetried", APIEvent::Type::AtomicOperationRetried)
		.value("AtomicOperationCompletedNonatomically", APIEvent::Type::AtomicOperationCompletedNonatomically)
		.value("WiVIStackRefreshFailed", APIEvent::Type::WiVIStackRefreshFailed)
		.value("WiVIUploadStackOverflow", APIEvent::Type::WiVIUploadStackOverflow)
		.value("I2CMessageExceedsMaxLength", APIEvent::Type::I2CMessageExceedsMaxLength)
		.value("A2BMessageIncompleteFrame", APIEvent::Type::A2BMessageIncompleteFrame)
		.value("CoreminiUploadVersionMismatch", APIEvent::Type::CoreminiUploadVersionMismatch)
		.value("DiskNotConnected", APIEvent::Type::DiskNotConnected)
		.value("UnexpectedResponse", APIEvent::Type::UnexpectedResponse)
		.value("LiveDataInvalidHandle", APIEvent::Type::LiveDataInvalidHandle)
		.value("LiveDataInvalidCommand", APIEvent::Type::LiveDataInvalidCommand)
		.value("LiveDataInvalidArgument", APIEvent::Type::LiveDataInvalidArgument)
		.value("LiveDataVersionMismatch", APIEvent::Type::LiveDataVersionMismatch)
		.value("LiveDataNoDeviceResponse", APIEvent::Type::LiveDataNoDeviceResponse)
		.value("LiveDataMaxSignalsReached", APIEvent::Type::LiveDataMaxSignalsReached)
		.value("LiveDataCommandFailed", APIEvent::Type::LiveDataCommandFailed)
		.value("LiveDataEncoderError", APIEvent::Type::LiveDataEncoderError)
		.value("LiveDataDecoderError", APIEvent::Type::LiveDataDecoderError)
		.value("LiveDataNotSupported", APIEvent::Type::LiveDataNotSupported)
		.value("LINSettingsNotAvailable", APIEvent::Type::LINSettingsNotAvailable)
		.value("ModeNotFound", APIEvent::Type::ModeNotFound)
		.value("AppErrorParsingFailed", APIEvent::Type::AppErrorParsingFailed)
		.value("GPTPNotSupported", APIEvent::Type::GPTPNotSupported)
		.value("SettingNotAvaiableDevice", APIEvent::Type::SettingNotAvaiableDevice)
		.value("DiskFormatNotSupported", APIEvent::Type::DiskFormatNotSupported)
		.value("DiskFormatInvalidCount", APIEvent::Type::DiskFormatInvalidCount)
		.value("FailedToRead", APIEvent::Type::FailedToRead)
		.value("FailedToWrite", APIEvent::Type::FailedToWrite)
		.value("DriverFailedToOpen", APIEvent::Type::DriverFailedToOpen)
		.value("DriverFailedToClose", APIEvent::Type::DriverFailedToClose)
		.value("PacketChecksumError", APIEvent::Type::PacketChecksumError)
		.value("TransmitBufferFull", APIEvent::Type::TransmitBufferFull)
		.value("DeviceInUse", APIEvent::Type::DeviceInUse)
		.value("PCAPCouldNotStart", APIEvent::Type::PCAPCouldNotStart)
		.value("PCAPCouldNotFindDevices", APIEvent::Type::PCAPCouldNotFindDevices)
		.value("PacketDecodingError", APIEvent::Type::PacketDecodingError)
		.value("SocketFailedToOpen", APIEvent::Type::SocketFailedToOpen)
		.value("FailedToBind", APIEvent::Type::FailedToBind)
		.value("ErrorSettingSocketOption", APIEvent::Type::ErrorSettingSocketOption)
		.value("GetIfAddrsError", APIEvent::Type::GetIfAddrsError)
		.value("SendToError", APIEvent::Type::SendToError)
		.value("MDIOMessageExceedsMaxLength", APIEvent::Type::MDIOMessageExceedsMaxLength)
		.value("VSABufferCorrupted", APIEvent::Type::VSABufferCorrupted)
		.value("VSATimestampNotFound", APIEvent::Type::VSATimestampNotFound)
		.value("VSABufferFormatError", APIEvent::Type::VSABufferFormatError)
		.value("VSAMaxReadAttemptsReached", APIEvent::Type::VSAMaxReadAttemptsReached)
		.value("VSAByteParseFailure", APIEvent::Type::VSAByteParseFailure)
		.value("VSAExtendedMessageError", APIEvent::Type::VSAExtendedMessageError)
		.value("VSAOtherError", APIEvent::Type::VSAOtherError)
		.value("ServdBindError", APIEvent::Type::ServdBindError)
		.value("ServdNonblockError", APIEvent::Type::ServdNonblockError)
		.value("ServdTransceiveError", APIEvent::Type::ServdTransceiveError)
		.value("ServdOutdatedError", APIEvent::Type::ServdOutdatedError)
		.value("ServdInvalidResponseError", APIEvent::Type::ServdInvalidResponseError)
		.value("ServdLockError", APIEvent::Type::ServdLockError)
		.value("ServdSendError", APIEvent::Type::ServdSendError)
		.value("ServdRecvError", APIEvent::Type::ServdRecvError)
		.value("ServdPollError", APIEvent::Type::ServdPollError)
		.value("ServdNoDataError", APIEvent::Type::ServdNoDataError)
		.value("ServdJoinMulticastError", APIEvent::Type::ServdJoinMulticastError)
		.value("ServdNotReachable", APIEvent::Type::ServdNotReachable)
		.value("DXXErrorSys", APIEvent::Type::DXXErrorSys)
		.value("DXXErrorInt", APIEvent::Type::DXXErrorInt)
		.value("DXXErrorOverflow", APIEvent::Type::DXXErrorOverflow)
		.value("DXXErrorIO", APIEvent::Type::DXXErrorIO)
		.value("DXXErrorArg", APIEvent::Type::DXXErrorArg)
		.value("NoErrorFound", APIEvent::Type::NoErrorFound)
		.value("TooManyEvents", APIEvent::Type::TooManyEvents)
		.value("Unknown", APIEvent::Type::Unknown)
		.finalize();

		pybind11::native_enum<APIEvent::Severity>(apiEvent, "Severity", "enum.IntEnum")
		.value("Any", APIEvent::Severity::Any)
		.value("EventInfo", APIEvent::Severity::EventInfo)
		.value("EventWarning", APIEvent::Severity::EventWarning)
		.value("Error", APIEvent::Severity::Error)
		.finalize();

	apiEvent
		.def("get_type", &APIEvent::getType)
		.def("get_severity", &APIEvent::getSeverity)
		.def("get_description", &APIEvent::getDescription)
		.def("describe", &APIEvent::describe)
		.def("__repr__", &APIEvent::describe);

	pybind11::classh<EventFilter>(m, "EventFilter")
		.def(pybind11::init())
		.def(pybind11::init<APIEvent::Type>())
		.def(pybind11::init<APIEvent::Severity>())
		.def_readwrite("type", &EventFilter::type)
		.def_readwrite("severity", &EventFilter::severity)
		.def_readwrite("serial", &EventFilter::serial);
}

} // namespace icsneo

