#include <vector>

#include <ev++.h>

#include "card_base.h"
#include "loc_tool.h"
#include "message.h"
#include "zloop.h"

#include "card_message_handle.h"

//一张卡一个ct的所有不同天线的信息
struct one_ct_message_handle
{
	static loc_tool_main m_loc_tool;
	ev::timer m_min_timer,m_max_timer;
	//loc_message.
	std::vector<loc_message> m_msg_list;
	card_location_base*m_card;
	const algo_config*m_ac=nullptr;
	int  m_ct;
	bool m_min_timeout=false;
	ev::dynamic_loop * m_loop = nullptr;
	one_ct_message_handle(card_location_base*card)
	{
		m_card=card;
		m_ct=-1;
	}

	void reset()
	{
		m_ct=-1;
		m_min_timeout=false;
		m_msg_list.clear();
	}

	void on_min_timer()
	{
		m_min_timer.stop();

		if((int)m_msg_list.size()>=m_ac->best_msg_cnt)
		{
			m_max_timer.stop();
			calc_location();
			return;
		}
		m_min_timeout=true;
	}

	void on_max_timer()
	{
		m_max_timer.stop();
		calc_location();
	}

	void set(ev::dynamic_loop * loop)
	{
		m_loop = loop;

		m_min_timer.set(*m_loop);
		m_min_timer.set<one_ct_message_handle,&one_ct_message_handle::on_min_timer>(this);
		m_max_timer.set(*m_loop);
		m_max_timer.set<one_ct_message_handle,&one_ct_message_handle::on_max_timer>(this);
	}

	void on_message(ev::dynamic_loop *loop,const message_locinfo&loc)
	{
		if(m_loop == nullptr && loop!=nullptr)
			set(loop);
		else if(loop == nullptr)
			return;
		if(!m_msg_list.empty()&& m_ct!=loc.m_card_ct)
		{
			m_msg_list.clear();
		}
		auto sitPtr = sit_list::instance()->get(loc.m_site_id);
		if(sitPtr==nullptr)
		{
			log_warn("分站信息缺失,SitId:%d",loc.m_site_id);
			return;
		}
		auto s=sit_list::instance()->get(loc.m_site_id);
		if(m_msg_list.empty())
		{
			m_ct=loc.m_card_ct;
			m_ac=&s->config();
			m_min_timeout=false;
			//这里构造loc_message 保存数据
			m_msg_list.push_back(loc_message(s,loc.m_tof,loc.m_time_stamp,loc.m_card_id,
						loc.m_card_ct,loc.m_card_type,loc.m_ant_id,loc.m_rav,loc.m_acc,
						loc.m_sync_ct,loc.m_rssi));

			//启动本CT的最小、最大两个定时器
			m_min_timer.start(m_ac->min_wait_time);
			m_max_timer.start(m_ac->max_wait_time);
			return;
		}

		m_msg_list.push_back(loc_message(s,loc.m_tof,loc.m_time_stamp,loc.m_card_id,
					loc.m_card_ct,loc.m_card_type,loc.m_ant_id,loc.m_rav,loc.m_acc,
					loc.m_sync_ct,loc.m_rssi));

		if(m_min_timeout && (int)m_msg_list.size()>=m_ac->best_msg_cnt)
		{
			calc_location();
			m_max_timer.stop();
		}
	}

	void calc_location()
	{
		auto v = m_msg_list;
		if(v.empty())
		{
			return;
		}

		log_info("calc_location_begin:card_id=%d,ct=%d,m_ct=%d",m_card->m_id,v[0].m_card_ct,m_ct);

		std::vector<point> rc=std::move(m_loc_tool.calc_location(v));
		log_info("calc_location:%d size:%d",m_card->m_id,rc.size());

		if(!rc.empty()) m_card->on_location(std::move(rc),v);

		reset();
		log_info("calc_location_end:card_id=%d",m_card->m_id);
	}
};

loc_tool_main one_ct_message_handle::m_loc_tool;

card_message_handle::card_message_handle(card_location_base*card)
{
	m_card=card;

	for(size_t i=0;i<m_ct_list.size();i++)
	{
		m_ct_list[i]=new one_ct_message_handle(card);
	}
}

card_message_handle::~card_message_handle()
{
	for(auto&it:m_ct_list)
	{
		delete it;
	}
}

void card_message_handle::on_message(zloop<task*> * loop,const message_locinfo&loc,bool is_history)
{
	if(is_history)
	{
		log_warn("%s","当前代码没有处理历史消息记录。");
		return;
	}
	STATUS_CARD c_status = STATUS_POWER_NOMARL;
	if(loc.m_batty_status == 2)
	{
		c_status = STATUS_POWER_LOWER_SERIOUS;
	}
	m_card->do_status(c_status);

	if(loc.m_callinfo & 0x80)
	{
		m_card->do_status(STATUS_HELP);
	}
	if((loc.m_callinfo & 0x01) || (loc.m_callinfo & 0x02))
	{
		m_card->do_status(STATUS_CALL);
	}

	m_ct_list[loc.m_card_ct&(m_ct_list.size()-1)]->on_message(loop,loc);
}