/*
 * @Author: your name
 * @Date: 2022-02-08 15:59:33
 * @LastEditors: your name
 * @LastEditTime: 2023-07-21 14:41:19
 * @Description: file content
 * @FilePath: /shigetai_lirs/nvidia_ascend_engine/nvidia_engine/MyYaml/MyYaml.h
 * 
 * Copyright © 2022 <Shandong Matrix Software Engineering Co., Ltd>
 */
#ifndef MYYAML_H_
#define MYYAML_H_

#include <map>
#include <mutex>
#include <fstream>
#include "yaml-cpp/yaml.h"


namespace ai_matrix
{
    //数据源参数
    struct DataSourceConfig
    {
        bool bUse;              //是否使用
        std::string strUrl;     //流地址
        int iSkipInterval;      //跳帧
        std::string strTarget;  //识别目标
        int iDirection;         //行驶方向  0-自动识别 1-向左 2-向右
        int iLeftFirst;         //0-向左编号在前 1-向左属性在前
        int iRightFirst;        //2-向右编号在前 3-向右属性在前
        float fIdentifyAreasLTX;//识别区域左上X坐标
        float fIdentifyAreasLTY;//识别区域左上Y坐标
        float fIdentifyAreasRBX;//识别区域右下X坐标
        float fIdentifyAreasRBY;//识别区域右下Y坐标
        int iRotate;            //图像旋转角度(0:不旋转[默认]; 90:顺时针旋转90度; 180:顺时针旋转180度; 270:顺时针旋转270度)
        std::map<int, int> mapClassMinH; //大框类别的最小高度
    };

    //模型参数
    struct ModelConfig
    {
        std::string strOmPath;          //om文件路径
        std::string strModelInfoPath;   //模型信息文件路径
        std::string strModelType;       //模型类型
        float fScoreThreshold;          //得分阈值
        float fNMSTreshold;             //nms阈值
    };

    class MyYaml final
    {
    public:
        static MyYaml *GetIns();
        //读yaml文件
        int ReadYaml(std::string &strPath);
        //写yaml文件
        int WriteYaml();
        std::string GetStringValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
        int GetIntValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
        bool GetBoolValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
        float GetFloatValue(const char *pszKey, const YAML::Node *pConfig = nullptr) const;
        std::string GetPathValue(const char *pszKey, const YAML::Node *pConfig =nullptr) const;
        //获取模型参数
        ModelConfig GetModelConfig(const std::string &strModleName) const;
        //获取所有数据源个数
        size_t GetDataSourceCount() const;
        //根据数据源ID获取数据源参数
        DataSourceConfig GetDataSourceConfigById(int iEngineId) const;
        //获取在用的数据源参数
        std::map<int, DataSourceConfig> GetUseDataSourceConfig() const;


        YAML::Node config_;

    private:
        MyYaml() = default;
        MyYaml(const MyYaml &) = delete;
        MyYaml(MyYaml &&) = delete;
        MyYaml &operator=(const MyYaml &) = delete;
        MyYaml &operator=(MyYaml &&) = delete;
        ~MyYaml() = default;


        static MyYaml *pInstance_;
        static std::mutex mx_; //锁，保证线程安全
        std::string strConfigYamlPath_;
        //数据源参数
        std::map<int, DataSourceConfig> mapDataSourceConfig_;
        std::map<int, DataSourceConfig> mapUseDataSourceConfig_;

        //模型参数
        std::map<std::string, ModelConfig> mapModelConfig_;

        //定义一个嵌套类，负责释放内存，操作系统自动完成，不用担心内存泄露
        class GarbageCollector
        {
        public:
            ~GarbageCollector()
            {
                if (MyYaml::pInstance_)
                {
                    delete MyYaml::pInstance_;
                    MyYaml::pInstance_ = nullptr;
                }
            }
        };
        static GarbageCollector gc_;
    };
}

#endif