#ifndef LIVOXPROTO1_H
#define LIVOXPROTO1_H

#include <boostAsioLinkageFix.h>
#include <memory>
#include <string>
#include <cstdint>
#include <functional>
#include <spinscale/callback.h>
#include <boost/asio/posix/stream_descriptor.hpp>

// Forward declarations
namespace smo {
namespace stim_buff {
	struct SmoCallbacks;
}
}
namespace sscl {
	class ComponentThread;
}

namespace livoxProto1 {
	class Device;
}

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Initialize the Livox protocol library
 * @param componentThread Component thread shared pointer
 * @param smoCallbacks Callbacks provided by SMO
 */
typedef void livoxProto1_mainFn(
	const std::shared_ptr<sscl::ComponentThread>& componentThread,
	const smo::stim_buff::SmoCallbacks& smoCallbacks);

/**
 * Cleanup the Livox protocol library
 */
typedef void livoxProto1_exitFn(void);

/**
 * Create a new Livox device connection
 * @param deviceIdentifier The device identifier (broadcast code)
 * @param componentThread Component thread for async operations
 * @param commandTimeoutMs Command timeout in milliseconds (default: 1000)
 * @param retryDelayMs Retry delay in milliseconds (default: 3000)
 * @param smoIp SMO IP address (empty string for auto-detection)
 * @param smoSubnetNbits SMO subnet mask bits (e.g., 24 for /24, 16 for /16)
 * @param dataPort Data port for point cloud (default: 56000)
 * @param cmdPort Command port (default: 56001)
 * @param imuPort IMU port (default: 56002)
 * @return Device pointer on success, nullptr on failure
 */
typedef std::function<
	void(bool success, std::shared_ptr<livoxProto1::Device> device)>
	livoxProto1_getOrCreateDeviceReqCbFn;

typedef void livoxProto1_getOrCreateDeviceReqFn(
	const std::string& deviceIdentifier,
	const std::shared_ptr<sscl::ComponentThread>& componentThread,
	int commandTimeoutMs, int retryDelayMs,
	const std::string& smoIp, uint8_t smoSubnetNbits,
	uint16_t dataPort,  uint16_t cmdPort, uint16_t imuPort,
	sscl::Callback<livoxProto1_getOrCreateDeviceReqCbFn> callback);

typedef std::function<void(bool success)> livoxProto1_destroyDeviceReqCbFn;
typedef void livoxProto1_destroyDeviceReqFn(
	std::shared_ptr<livoxProto1::Device> device,
	sscl::Callback<livoxProto1_destroyDeviceReqCbFn> callback);

typedef std::function<void(bool success)>
	livoxProto1_device_enablePcloudDataReqCbFn;
typedef void livoxProto1_device_enablePcloudDataReqFn(
	std::shared_ptr<livoxProto1::Device> device,
	sscl::Callback<livoxProto1_device_enablePcloudDataReqCbFn> callback);

typedef std::function<void(bool success)>
	livoxProto1_device_disablePcloudDataReqCbFn;
typedef void livoxProto1_device_disablePcloudDataReqFn(
	std::shared_ptr<livoxProto1::Device> device,
	sscl::Callback<livoxProto1_device_disablePcloudDataReqCbFn> callback);

typedef std::function<void(bool success, uint8_t returnMode)>
	livoxProto1_device_getReturnModeReqCbFn;
typedef void livoxProto1_device_getReturnModeReqFn(
	std::shared_ptr<livoxProto1::Device> device,
	sscl::Callback<livoxProto1_device_getReturnModeReqCbFn> callback);

typedef std::shared_ptr<boost::asio::posix::stream_descriptor>
	livoxProto1_getPcloudDataFdDescFn(void);

livoxProto1_mainFn livoxProto1_main;
livoxProto1_exitFn livoxProto1_exit;
livoxProto1_getOrCreateDeviceReqFn livoxProto1_getOrCreateDeviceReq;
livoxProto1_destroyDeviceReqFn livoxProto1_destroyDeviceReq;
livoxProto1_device_enablePcloudDataReqFn livoxProto1_device_enablePcloudDataReq;
livoxProto1_device_disablePcloudDataReqFn
	livoxProto1_device_disablePcloudDataReq;
livoxProto1_device_getReturnModeReqFn livoxProto1_device_getReturnModeReq;
livoxProto1_getPcloudDataFdDescFn livoxProto1_getPcloudDataFdDesc;

#ifdef __cplusplus
}
#endif

#endif // LIVOXPROTO1_H
