/*
 * @Description: 任务中心
 * @Version: 1.0
 * @Autor: lishengyin
 * @Date: 2022-04-07 17:19:19
 * @LastEditors: lishengyin
 * @LastEditTime: 2022-06-08 11:50:41
 */
#include "TaskCenter.hpp"
#include "Disposition.hpp"
#include "Sectorpower.hpp"

namespace ins
{  
    static std::shared_ptr<TaskCenter> m_TaskCenter = nullptr;

    /**
     * @description: 构造函数
     * @param {*}
     * @return {*}
     */    
    TaskCenter::TaskCenter(): Module("TaskCenter"){
        //Init();
    }

    /**
     * @description: 创建实例
     * @param {*}
     * @return {*}
     */
    std::shared_ptr<TaskCenter> TaskCenter::CreateNew(){
        if(m_TaskCenter == nullptr)  m_TaskCenter = std::shared_ptr<TaskCenter>(new TaskCenter);
        return m_TaskCenter;
    }

    /**
     * @description: 创建实例
     * @param {*}
     * @return {*}
     */
    std::shared_ptr<TaskCenter> TaskCenter::getPtr(){
        return m_TaskCenter;
    }

    /**
     * @description: 初始化
     * @param {*}
     * @return {*}
     */    
    int8_t TaskCenter::Init(){
        if(this->valid) return OK;
        Disposition::Ptr disposition = Disposition::getPtr();
        for(int i = 0; i < disposition->ayncThreadNum; i++){
            workers.push_back(thread([this](){
                while (true){
                    // 获取任务
                    ins::InsTask::Ptr task = nullptr;
                    {
                        std::unique_lock<std::mutex> lock(m_mutex);
                        condition.wait(lock, [this](){
                            return stop || !async_Tasks.empty();
                        });
                        if(stop && async_Tasks.empty()) return;
                        task = async_Tasks.front();
                        async_Tasks.pop();
                    }
                    // 进入审批流程
                    if(task != nullptr || Sectorpower::getPtr()->reviewTask(task) != true) (*task->getTask())();
                }
            }));
        }
        this->valid = true;
        this->stop = false;
        return OK;
    }

    /**
     * @description: 释放
     * @param {*}
     * @return {*}
     */    
    void TaskCenter::Destroy() {
        {
            std::unique_lock<std::mutex> lock(m_mutex);
            stop = true;
        }
        condition.notify_all();
        for(auto &worker :workers)
        {
            worker.join();
        } 
    }
    
    /**
     * @description: 任务入队
     * @param {Ptr&} task 任务
     * @return {*}
     */    
    int8_t TaskCenter::enqueue(ins::InsTask::Ptr& task){
        if(task == nullptr || this->valid == false) return ERR;
        switch (task->getFlag())
        {
        //* 异步任务
        case InsTaskFlag::INS_TASK_ASYNC_FLAG :
            {
                std::unique_lock<std::mutex> lock(m_mutex);
                if(stop) break;
                async_Tasks.push(task);
            }
            condition.notify_one();
            break;

        //* 同步任务
        case InsTaskFlag::INS_TASK_SYNC_FLAG :
            //* 同步执行
            std::shared_ptr<thread> th = std::make_shared<thread>([task](){
                (*task->getTask())();
            });
            // 执行
            if(th == nullptr) return ERR;
            th->join();
            break;
        }
        if(stop) return ERR;
        return OK;
    }

    /**
     * @description: 处理任务
     * @param {Ptr&} pack
     * @return {*}
     */    
    int8_t TaskCenter::ProcessingPacket(InsPacket::Ptr& pack){
        ins::InsTask::Ptr task = Sectorpower::getPtr()->getWorkflowTask(pack);
        if(task == nullptr) return ERR;
        // 入队任务
        return enqueue(task);
    }
} // namespace ins
