#ifndef MODULE_AREA_OVER_SPEED_H
#define MODULE_AREA_OVER_SPEED_H

/**
  *@brief 区域超速模块
  * 当某张车卡速度超过某个区域的最大速度时，发出告警
  * @author 戴月腾
  * @date 2018-08-08
*/

#include <mutex>
#include <map>
#include <chrono>
#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "module_const.h"

/**
 * @brief 区域超速类。当某张车卡速度超过某个区域的最大速度时，发出告警, 单例
 */
class module_area_over_speed:public singleton_base<module_area_over_speed>
{
private:
    friend class singleton_base<module_area_over_speed>;
    module_area_over_speed()
    {
    }

public:

    void on_enter(std::shared_ptr<card> card_ptr,std::shared_ptr<area_hover>&c,double speed)
    {
        card_ptr->m_speed = speed;
        c->m_vehicle_area_over_speed_count=0;
        c->m_vehicle_area_normal_speed_count=0;
        c->m_is_area_over_speed_vehicle=false;

        auto area_ptr = c->m_area;
        if(area_ptr->m_limit_speed > speed)//速度正常
        {
            c->m_vehicle_area_normal_speed_count++;
        }
        else//超速
        {
            c->m_vehicle_area_over_speed_count++;
        }
    }

    void on_hover(std::shared_ptr<card> card_ptr,std::shared_ptr<area_hover>&c,double speed,
                  std::map<uint64_t, std::shared_ptr<ya_event>>& ev_map)
    {
        card_ptr->m_speed = speed;

        auto area_ptr = c->m_area;
        if(area_ptr->m_limit_speed > speed)//速度正常
        {
            c->m_vehicle_area_normal_speed_count++;
        }
        else//超速
        {
            c->m_vehicle_area_over_speed_count++;
        }

        //确定超速
        if(global_constant::AREA_SPEED_COUNT_LIMIT <= c->m_vehicle_area_over_speed_count)
        {
            c->m_vehicle_area_over_speed_count=global_constant::AREA_SPEED_COUNT_LIMIT;

            auto ev_ptr = tool_other::find_event(card_ptr->m_id, ET_CARD_AREA_OVER_SPEED, ev_map);
            if(ev_ptr)
            {
                ev_ptr->m_limit_value=area_ptr->m_limit_speed;
                ev_ptr->m_cur_value=card_ptr->m_speed;
            }
            else//从没有告警状态转化为告警状态
            {
                c->m_is_area_over_speed_vehicle=true;
                c->m_vehicle_area_normal_speed_count=0;

                auto ev_ptr = tool_other::create_event(OT_CARD, card_ptr->m_id, ET_CARD_AREA_OVER_SPEED);

                tool_other::copy_event(card_ptr, ev_ptr);

                ev_ptr->m_limit_value = area_ptr->m_limit_speed;
                ev_ptr->m_cur_value = card_ptr->m_speed;

                //保存到数据库
                tool_db::save_event(ev_ptr);

                tool_other::insert_event(ev_ptr, ev_map);
            }
        }

        //确定速度正常
        if(global_constant::AREA_SPEED_COUNT_LIMIT <= c->m_vehicle_area_normal_speed_count)
        {
            c->m_vehicle_area_normal_speed_count=global_constant::AREA_SPEED_COUNT_LIMIT;

            if(c->m_is_area_over_speed_vehicle)
            {
                c->m_is_area_over_speed_vehicle = false;
                c->m_vehicle_area_over_speed_count=0;

                auto ev_ptr = tool_other::find_event(card_ptr->m_id, ET_CARD_AREA_OVER_SPEED, ev_map);
                if(ev_ptr)
                {
                    ev_ptr->m_status = ES_END;

                    ev_ptr->m_limit_value = area_ptr->m_limit_speed;
                    ev_ptr->m_cur_value = speed;
                    ev_ptr->m_cur_time = std::chrono::system_clock::now();

                    //保存到数据库
                    tool_db::save_event(ev_ptr);
                }
            }
        }
    }

    void on_leave(std::shared_ptr<card> card_ptr,std::shared_ptr<area_hover>&c,double speed)
    {

    }
};
typedef std::shared_ptr<module_area_over_speed> module_area_over_speed_ptr;

#endif
