/*
 * @Description: 
 * @Version: 1.0
 * @Autor: lishengyin
 * @Date: 2022-03-09 10:55:43
 * @LastEditors: lishengyin
 * @LastEditTime: 2022-07-22 16:57:12
 */
#ifndef __INFINEFILTER_H_
#define __INFINEFILTER_H_

#include <iostream>
#include "Notices.h"
#include "Util/util.h"
#include "Util/logger.h"
#include "Network/Socket.h"
#include "Util/TimeTicker.h"
#include "Util/NoticeCenter.h"
#include "Poller/Timer.h"
#include "CNStreamInferData.h"
#include "config.hpp"
#include <cmath>

using namespace std;
using namespace toolkit;

// 推理过滤器
class InfineFilter
{
private:
    struct HistoryData
    {
        std::shared_ptr<Ticker> ticker = nullptr;
        std::shared_ptr<CNStreamInferData> CnStreamInferData = nullptr;
    };
    
private:
    InfineFilter(){
    }

    InfineFilter(InfineFilter&) = delete;

    InfineFilter& operator=(const InfineFilter&) = delete;

    // 灵敏度  0,1,2,3 
    // 0 - 不过滤
    // 1 - 参考上一个坐标、大小、数量, 如果类似则过滤
    // 2 - 在1的基础上加入 时间间隔,如每2秒取一次结果
    // 3 - 记录每一个结果,并设置超时机制,未超时时：判断当前推理结果与过去的坐标、大小、数量是否类似，类似则过滤
    //     超时时：舍弃历史记录
    int sensitivity = 2; // 灵敏度 

    int interval = 2000; // 时间间隔

    vector<HistoryData> HistoryDatas;

    int TimeOut = 10 * 60 * 1000;
    
    Timer::Ptr timer = nullptr;


private:
    /**
     * @description: 跟上一次的判断结果
     * @param {*}
     * @return {*}
     */    
    int8_t LastOneJudgment(std::shared_ptr<CNStreamInferData>& cnStreamInferData);

    /**
     * @description:时间间隔
     * @param {*}
     * @return {*}
     */    
    int8_t IntervalJudgment();

    /**
     * @description: 历史判定
     * @param {*}
     * @return {*}
     */    
    int8_t HistoricalJudgment(std::shared_ptr<CNStreamInferData>& cnStreamInferData);

    /**
     * @description: 历史数据检查
     * @param {*}
     * @return {*}
     */    
    void HistoricalCheck();

public:
    using Ptr = std::shared_ptr<InfineFilter>;

    ~InfineFilter(){}

    /**
     * @description: 小目标过滤器
     * @return {*}
     */    
    int8_t MinBBoxFilter(std::shared_ptr<CNStreamInferData>& cnStreamInferData);

    /**
     * @description: 判定结果
     * @param {*}
     * @return {*}
     */
    int8_t judgementResult(std::shared_ptr<CNStreamInferData>& cnStreamInferData);

    /**
     * @description: 判定是否相识
     * @param {InferInfo&} infer1
     * @param {InferInfo&} infer2
     * @return {*}
     */    
    int8_t CalculateSimilarity(InferInfo& infer1, InferInfo& infer2);

    /**
     * @description: 获取ptr
     * @param {*}
     * @return {*}
     */    
    static std::shared_ptr<InfineFilter> getPtr();

    /**
     * @description: 设置灵敏度
     * @param {int} Sensitivity
     * @return {*}
     */    
    int8_t setSensitivity(int Sensitivity);

    /**
     * @description: 设置时间间隔
     * @param {int} Interval
     * @return {*}
     */    
    int8_t setInterval(int Interval);

    /**
     * @description: 设置超时时间
     * @param {int} timeOut
     * @return {*}
     */    
    int8_t setTimeOut(int timeOut);

public:
     double bboxSize = 0.0;
};



#endif