/**
 *  集装箱选取最优结果Engine
 * */

#ifndef SELECTBESTCONTAINERENGINE_H
#define SELECTBESTCONTAINERENGINE_H

#include "AppCommon.h"
#include "MyYaml.h"
#include "EngineBase.h"
#include "EngineFactory.h"

class SelectBestContainerEngine : public ai_matrix::EngineBase
{
public:
    SelectBestContainerEngine();
    ~SelectBestContainerEngine();

    APP_ERROR Init() override;
    APP_ERROR DeInit() override;
    APP_ERROR Process() override;

private:
    
    //初始化参数信息
    void InitParam();
    //验证集装箱号是否满足规则(前10位依次与2^0 ~2^9相乘）/11 所得余数，即是校验位)
    bool VerifyContainerNo(std::string &strContainerNo);
    //构造最优集装箱信息
    void MakeBestContainer(Container &containerBest,
                           TransSubData *pTransSubData,
                           std::shared_ptr<ProcessData> pProcessData);

    void DealFailContianer(TransSubData &transSubData, std::shared_ptr<ProcessData> pProcessData, int iIndex,
                           std::map<int, TrainContainer> &mapTCFail);
    void DealSuccContianer(TransSubData &transSubData, std::shared_ptr<ProcessData> pProcessData, int iIndex,
                           std::map<int, TrainContainer> &mapTCSucc);
    void SelectBestTrainContainer(std::shared_ptr<TrainContainer> pTrainContainer);
    void DealContainer(std::shared_ptr<ProcessData> pProcessData, TransSubData &transSubData,
                       std::map<int, TrainContainer> &mapTCSucc, std::map<int, TrainContainer> &mapTCFail,
                       std::map<int, Step1Location> &mapStep1Pre, std::map<int, bool> &mapSecondFlag);

    std::string strPort0_;
    std::string strPort1_;
    std::map<int, bool> mapDataSourceIsEnd_;                    //[key-数据源id, value-数据是否结束]
    std::set<int> setTopContainerSid_;                          //[顶部集装箱数据源ID]

    //正向信息
    std::map<int, TrainContainer> mapTCFail0_;                  //[key-数据源id, value-校验失败的集装箱信息]
    std::map<int, TrainContainer> mapTCSucc0_;                  //[key-数据源id, value-校验成功的集装箱信息]
    std::map<int, Step1Location> mapStep1Pre0_;                 //[key-数据源id, value-上一帧大框信息]
    std::map<int, bool> mapSecondFlag0_;                        //[key-数据源id, value-是否保存第2个箱号]

    //反向信息
    std::map<int, TrainContainer> mapTCFail1_;                  //[key-数据源id, value-校验失败的集装箱信息]
    std::map<int, TrainContainer> mapTCSucc1_;                  //[key-数据源id, value-校验成功的集装箱信息]
    std::map<int, Step1Location> mapStep1Pre1_;                 //[key-数据源id, value-上一帧大框信息]
    std::map<int, bool> mapSecondFlag1_;                        //[key-数据源id, value-是否保存第2个箱号]

    //集装箱号转换
    std::map<std::string, int> mapExchange_ = {
        {"A", 10},
        {"B", 12},
        {"C", 13},
        {"D", 14},
        {"E", 15},
        {"F", 16},
        {"G", 17},
        {"H", 18},
        {"I", 19},
        {"J", 20},
        {"K", 21},
        {"L", 23},
        {"M", 24},
        {"N", 25},
        {"O", 26},
        {"P", 27},
        {"Q", 28},
        {"R", 29},
        {"S", 30},
        {"T", 31},
        {"U", 32},
        {"V", 34},
        {"W", 35},
        {"X", 36},
        {"Y", 37},
        {"Z", 38},
        {"0", 0},
        {"1", 1},
        {"2", 2},
        {"3", 3},
        {"4", 4},
        {"5", 5},
        {"6", 6},
        {"7", 7},
        {"8", 8},
        {"9", 9},
    };
};

ENGINE_REGIST(SelectBestContainerEngine)

#endif
