/**
  * @project ALG_WHeelData
  * @brief   $BRIEF$
  * @author  lz
  * @data    2023/4/21
 **/
#pragma once

#include <iostream>
#include <thread>
#include "json/json.h"
#include "AlgWheelDetect/cloud_data.h"
#include "AlgWheelDetect/detect_wheel.h"
#include "define.pb.h"
#include "rabbitmq.h"
#include "message/measure_message.pb.h"
#include "trajxtory_regression.hpp"

#define NO_MQTT_GET_CLOUD 1

class VelodyneManager {
public:
    /**
      * @brief   根据指定的配置文件启动测量功能。
      * @param   path 配置文件路径，json文件格式且符合proto配置的内容
      */
    bool run_measure_form(const std::string &path);

private:
    /**
      * @brief   初始化glog日志系统
      * @return  是否成功
      */
    bool initGlog();

    /**
      * @brief   初始化测量配置
      * @注      配置初始化失败很有可能是配置文件错了，配置文件不能多出不相关字段
      * @return  是否成功
      */
    bool initMeasureConfig(const std::string &path);

    /**
      * @brief   线程函数，每个入口一个线程，线程中会根据入口雷达数据进行算法检测，测出入口车辆信息
      * @param   config 该线程对应的雷达信息的配置以及结果发送到哪个key（rabbitmq）或者topic（mqtt）
      * @param   mqtt_client mqtt类，通过这个向mqtt发送测量结果;
      */
    void thread_func(const MeasureLidar &config, CloudDataMqttAsync &mqtt_client);

    /**
      * @brief   将监听的话题的雷达数据全部集合在一起
      * @param   MeasureLidar 该线程的测量雷达相关配置
      * @param   cloud 点云数据
      * @return  NULL
      */
    bool getTopicsLidarData(const MeasureLidar &config, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud);

    /**
      * @brief   对检测结果进行对比分析，并将最终信息按照约定协议存储
      * @param   NULL
      * @return  NULL
      */
    bool packMeasureInfo(DetectWheel &detect, measure_statu &measure);


    // 测试用代码，有时候数据需要旋转
    bool getLocalPointCloud(const std::string &path, pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud);

private:
    MeasureConfig *m_measure_config;
    CloudDataMqttAsync *m_mqtt_client;
    DetectResultRabbitmq *m_detect_result_rabbitmq;
};
