/*
 * engine基类
 */

#ifndef INC_ENGINE_BASE_H
#define INC_ENGINE_BASE_H

#include <unistd.h>
#include <thread>
#include <vector>
#include <map>
#include <atomic>
#include <sys/time.h>

#ifdef ASCEND
#include "acl/acl.h"
#include "DvppCommon.h"
#include "Statistic.h"
#include "ModelProcess.h"
#include "ResourceManager.h"
#endif

#include "ErrorCode.h"
#include "Log.h"
#include "FileManager.h"
#include "CommonDataType.h"

#include "myqueue.h"
#include "myshell.h"

#include <NvInfer.h>
#include "logging.h"
#include <NvInferPlugin.h>
#include <NvOnnxParser.h>
#include <NvCaffeParser.h>


namespace ai_matrix
{
    struct EngineInitArguments
    {
        int32_t deviceId = 0;

        #ifdef ASCEND
        aclrtRunMode runMode;
        aclrtContext context;
        #endif

        std::string engineName = {};
        int engineId = -1;
        void *userData = nullptr;
    };

    class EngineBase
    {
    public:
        EngineBase() {}
        virtual ~EngineBase() {} //必须是虚函数

        void AssignInitArgs(const EngineInitArguments &initArgs);

        //每个engine自己实现
        virtual APP_ERROR Init(void) = 0;
        virtual APP_ERROR DeInit(void) = 0;

        APP_ERROR Run(void);
        APP_ERROR Stop(void);

        //设置输入队列
        void SetInputMap(std::string engineAddress, std::shared_ptr<MyQueue<std::shared_ptr<void>>> inputQueue);
        //得到输入队列
        std::shared_ptr<MyQueue<std::shared_ptr<void>>> GetInputMap(std::string engineAddress);

        //设置输出队列
        void SetOutputMap(std::string engineAddress, std::shared_ptr<MyQueue<std::shared_ptr<void>>> outputQue);

        void setLoggerPoint(Logger *gLogger_in);
 
        //线程函数
        void ProcessThread();
       //每个engine自己实现线程执行函数
        virtual APP_ERROR Process() = 0;
        std::string engineName_ = {}; //类名

    protected:
        std::atomic_bool isStop_ = {true}; //线程默认不启动
        //Logger *gLogger_obj = nullptr;
        int32_t deviceId_ = -1;
 
        #ifdef ASCEND
        aclrtContext aclContext_;
        aclrtRunMode runMode_;
        #endif

        //输入队列map
        std::map<std::string, std::shared_ptr<MyQueue<std::shared_ptr<void>>>> inputQueMap_ = {};
        //输出队列map
        std::map<std::string, std::shared_ptr<MyQueue<std::shared_ptr<void>>>> outputQueMap_ = {};

        int engineId_ = -1;           //实例化id
        
        std::thread processThr_ = {};
    };
}

#endif
