/*
 * @Author: yct 18202736439@163.com
 * @Date: 2022-09-30 18:11:59
 * @LastEditors: yct 18202736439@163.com
 * @LastEditTime: 2023-01-17 15:41:04
 * @FilePath: /puai_wj_2021/system/system_communication mq.cpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
//
// Created by huli on 2020/6/28.
//

#include "system_communication_mq.h"
#include "../system/system_executor.h"

System_communication_mq::System_communication_mq()
{
    dispatch_plc_passway_status t_dispatch_region_info;
    t_dispatch_region_info.set_turnplate_angle_min(-5);
    t_dispatch_region_info.set_turnplate_angle_max(5);
    dispatch_region_info_map.insert(std::pair<int, dispatch_plc_passway_status>(3117, t_dispatch_region_info));
    dispatch_region_info_map.insert(std::pair<int, dispatch_plc_passway_status>(3118, t_dispatch_region_info));
    dispatch_region_info_map.insert(std::pair<int, dispatch_plc_passway_status>(3219, t_dispatch_region_info));
}

System_communication_mq::~System_communication_mq()
{

}


//检查消息是否有效, 主要检查消息类型和接受者, 判断这条消息是不是给我的.
Error_manager System_communication_mq::check_msg(Rabbitmq_message*  p_msg)
{
	return SUCCESS;
}

//检查执行者的状态, 判断能否处理这条消息, 需要子类重载
Error_manager System_communication_mq::check_executer(Rabbitmq_message*  p_msg)
{
	return SUCCESS;
}

//处理消息, 需要子类重载
Error_manager System_communication_mq::execute_msg(Rabbitmq_message* p_msg)
{
//    return SUCCESS;
    return execute_dispatch_status_msg(p_msg);
}

//定时封装发送消息, 一般为心跳和状态信息, 需要子类重载
Error_manager System_communication_mq::auto_encapsulate_status()
{
//    return SUCCESS;
	return System_executor::get_instance_references().encapsulate_send_mq_status();
}

Error_manager System_communication_mq::execute_dispatch_status_msg(Rabbitmq_message* p_msg)
{
    std::unique_lock<std::mutex> t_lock(m_lock);

    if (p_msg->m_routing_key.find("dispatch_") != std::string::npos &&
        p_msg->m_routing_key.find("_statu_port") != std::string::npos)
    {
        dispatch_node_statu t_dispatch_node_statu;
        if(google::protobuf::TextFormat::ParseFromString(p_msg->m_message_buf, &t_dispatch_node_statu))
        {
            int t_terminal = t_dispatch_node_statu.unit_id();
            if (t_terminal == 31) {
                dispatch_region_info_map[3117] = t_dispatch_node_statu.dispatch_plc_passway_status_vector(0);
                dispatch_region_info_map[3118] = t_dispatch_node_statu.dispatch_plc_passway_status_vector(1);
            }
            if (t_terminal == 32) {
                dispatch_region_info_map[3219] = t_dispatch_node_statu.dispatch_plc_passway_status_vector(0);
            }
        }
    }

	//终端点击存车时, 发送存车表单给检查节点, 这里顺便发送给感测节点.
	if (p_msg->m_routing_key == "user_park_command_request_port")
	{
		park_table t_park_table_msg; //存车表单
		LOG(INFO) << "Receive p_msg " << " --- " << this;
		if(google::protobuf::TextFormat::ParseFromString(p_msg->m_message_buf, &t_park_table_msg))
		{
			std::string t_string = t_park_table_msg.DebugString();
			LOG(INFO) << "ParseFromString success, it's id: "<< t_park_table_msg.terminal_id() << " --- " ;
            // 给唐有成, 这里面有terminal_id(范围1-6), 可以触发感测节点保存事件.

            //  added by yct for region cloud saving function
            //  vlp16 region
            std::map<int, Ground_region *> t_ground_region_map = Velodyne_manager::get_instance_references().get_ground_region_map();
            int region_index = 0;
            for (auto iter = t_ground_region_map.begin(); iter != t_ground_region_map.end(); ++iter)
            {
                // get clouds from corresponding region
                if(t_park_table_msg.terminal_id() == iter->second->get_terminal_id())
                {
                    pcl::PointCloud<pcl::PointXYZ>::Ptr t_total_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
                    pcl::PointCloud<pcl::PointXYZ>::Ptr t_trans_total_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
                    pcl::PointCloud<pcl::PointXYZ>::Ptr t_filtered_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
                    pcl::PointCloud<pcl::PointXYZ>::Ptr t_failture_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
                    iter->second->get_region_cloud(t_total_cloud, Ground_region::Region_cloud_type::total);
                    iter->second->get_region_cloud(t_trans_total_cloud, Ground_region::Region_cloud_type::trans);
                    iter->second->get_region_cloud(t_filtered_cloud, Ground_region::Region_cloud_type::filtered);
                    iter->second->get_region_cloud(t_failture_cloud, Ground_region::Region_cloud_type::failure);
                    PathCreator pc;
                    pc.Mkdir(ETC_PATH"MeasureNode/data/");
                    if(pc.CreateDatePath(pc.GetCurPath()+"/"+std::to_string(t_park_table_msg.terminal_id())+"/", true))
                    {
                        save_cloud_txt(t_total_cloud, pc.GetCurPath() + t_park_table_msg.car_number() + "-total.txt");
                        save_cloud_txt(t_trans_total_cloud, pc.GetCurPath() + t_park_table_msg.car_number() + "-t_trans_total_cloud.txt");
                        save_cloud_txt(t_filtered_cloud, pc.GetCurPath() + t_park_table_msg.car_number() + "-filtered.txt");
                        if (!t_failture_cloud->empty()) {
                            save_cloud_txt(t_failture_cloud, pc.GetCurPath() + t_park_table_msg.car_number() + "-failture.txt");
                        }
                        LOG(INFO) <<"total and filtered cloud in region "<<t_park_table_msg.terminal_id()<<"(1-6) has been saved in "<<pc.GetCurPath();
                    }
                }
            }
        }
        // 指令信息必须手动ack, 这样才能清除服务器的指令,
		// (状态消息临时队列接受后自动清除, 指令消息永久队列接收后手动清除)
		// ack_msg(p_msg);
	}

	return SUCCESS;
}







