/**
  * @project ALG_WHeelData
  * @brief   从mqtt服务器获取点云数据并进行处理，仅给外部一个获取数据的接口。
  * @author  lz
  * @data    2023/4/21
 **/
#pragma once

#include "pahoc/mqtt_async.h"
#include "message/unpacket.hpp"
#include "defines.hpp"
#include <vector>
#include <memory>
#include <typeinfo>

// TODO: 完善功能
class CloudDataMqttAsync : public MqttAsyncClient {
public:
    CloudDataMqttAsync() = default;

    ~CloudDataMqttAsync() = default;

    static CloudDataMqttAsync *instance() {
        static CloudDataMqttAsync *p = nullptr;
        if (p == nullptr) {
            p = new CloudDataMqttAsync();
            p->init();
        }
        return p;
    }

    bool init();

    bool getCloudData(const std::string &topic, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud);

    bool getCloudData(const std::string &topic, pcl::PointCloud<pcl::PointXYZI>::Ptr &cloud);

    bool getCloudData(const std::string &topic, pcl::PointCloud<pcl::PointRPRY>::Ptr &cloud);

    bool getCloudData(const std::string &topic, pcl::PointCloud<pcl::PointALL>::Ptr &cloud);

private:
    static int CloudDataArrived(MqttAsyncClient *client, char *topicName, int topicLen, MQTTAsync_message *message);

    bool insertCloudData(std::string &topic, unsigned char *cloud_data, int size);

private:
    const char *MQTT_CONFIG_PATH = ETC_PATH"/etc/icp_mqtt_async.json";
    CloudPointUnpacket *m_unpacket;
    pcl::PointCloud<pcl::PointXYZI>::Ptr m_clouds;

    std::mutex m_cloud_mutex;
    std::map<std::string, pcl::PointCloud<pcl::PointALL>::Ptr> m_full_clouds_map;
    std::map<std::string, std::chrono::steady_clock::time_point> m_cloud_time_stamp_map;
};
