#include "AlgorithmTaskManage.h"

AlgorithmTaskManage::AlgorithmTaskManage(int humanDetectionLen):semaphore(humanDetectionLen),
    plateSemaphore(humanDetectionLen){
    this->humanDetectionLen=humanDetectionLen;
}

void AlgorithmTaskManage::initHumanDetectionManage(const QString &modelPaths,
                                                   float carShapeConfidence,float &height_reference,int &uniformColor) {
    for (int i = 0; i < humanDetectionLen; ++i) {
        HumanDetection* human=new HumanDetection(modelPaths,carShapeConfidence);
        human->setHuManParameter(height_reference,uniformColor);
        humanDetections.emplace_back(human);
    }
}
void AlgorithmTaskManage::initLicensePlateManage(const QString &modelPaths,
                                                 float carConfidence){
    for (int i = 0; i < humanDetectionLen; ++i) {
        LicensePlateRecognition* licensePlateRecognition=new LicensePlateRecognition(modelPaths,carConfidence);
        licensePlateRecognitions.emplace_back(licensePlateRecognition);
    }
    
}
AlgorithmTaskManage::~AlgorithmTaskManage(){
    Common & instace= Common::getInstance();
    
    for (auto task:humanDetections) {
        instace.deleteObj(task);
    }
    for (auto plate:licensePlateRecognitions) {
        instace.deleteObj(plate);
    }
}

void* AlgorithmTaskManage::schedulingAlgorithm(int scheType) {
    if (scheType == 0x01) {
        std::lock_guard<std::mutex> lock(mtxHuman);
        // 获取当前时间作为基准
        qint64 currentTime = QDateTime::currentSecsSinceEpoch();

        qint64 maxWaitTime = 0;
        // 记录最大等待时间的对象数量
        int maxWaitTimeCount = 0;
        std::vector<HumanDetection*> schedulableObjects;

        // 遍历humanDetections，找到所有等待时间相同的未执行的HumanDetection对象
        for (HumanDetection* human : humanDetections) {
            if (human->getIsRunning()) continue;

            // 计算此对象自上次执行以来的等待时间
            qint64 waitTime = std::abs(currentTime - human->getThreadTime());
            if (waitTime > maxWaitTime) {
                schedulableObjects.clear();
                schedulableObjects.push_back(human);
                maxWaitTime = waitTime;
                maxWaitTimeCount = 1;
            } else if (waitTime == maxWaitTime) {
                schedulableObjects.push_back(human);
                maxWaitTimeCount++;
            }
        }
        // 如果最大等待时间的对象数量为1，直接返回
        if (maxWaitTimeCount == 1) {
            return schedulableObjects.at(0);
        }
        if (schedulableObjects.empty()) {
            return nullptr;  // 如果没有可调度对象，返回 nullptr 或进行适当处理
        }
        // 在可调度的对象中随机选择一个
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0, schedulableObjects.size() - 1);

        return schedulableObjects[dis(gen)];
    } else if (scheType == 0x02) {
        std::lock_guard<std::mutex> lock(mtxLicense);
        // 获取当前时间作为基准
        qint64 currentTime = QDateTime::currentSecsSinceEpoch();

        qint64 maxWaitTime = 0;
        // 记录最大等待时间的对象数量
        int maxWaitTimeCount = 0;
        std::vector<LicensePlateRecognition*> schedulableObjects;

        // 遍历licensePlateRecognitions，找到所有等待时间相同的未执行的LicensePlateRecognition对象
        for (LicensePlateRecognition* licensePlateRecognition : licensePlateRecognitions) {
            if (licensePlateRecognition->getIsRunning()) continue;

            // 计算此对象自上次执行以来的等待时间
            qint64 waitTime = std::abs(currentTime - licensePlateRecognition->getThreadTime());
            if (waitTime > maxWaitTime) {
                schedulableObjects.clear();
                schedulableObjects.push_back(licensePlateRecognition);
                maxWaitTime = waitTime;
                maxWaitTimeCount = 1;
            } else if (waitTime == maxWaitTime) {
                schedulableObjects.push_back(licensePlateRecognition);
                maxWaitTimeCount++;
            }
        }
        // 如果最大等待时间的对象数量为1，直接返回
        if (maxWaitTimeCount == 1) {
            return schedulableObjects.at(0);
        }
        if (schedulableObjects.empty()) {
            return nullptr;  // 如果没有可调度对象，返回 nullptr 或进行适当处理
        }
        // 在可调度的对象中随机选择一个
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0, schedulableObjects.size() - 1);

        return schedulableObjects[dis(gen)];
    } else {
        qInfo() << "参数错误";
        return nullptr;
    }
}


void AlgorithmTaskManage::executeFindlicensePlateNumber(const cv::Mat &source, QString &lpNumber,vides_data::requestLicensePlate &plate,
                                                        qint64 currentTime,QString sSn){
    plateSemaphore.acquire();
    ScopeSemaphoreExit guard([this]() {
        plateSemaphore.release();  // 释放信号量
    });
    auto* selectedLicensePlate = static_cast<LicensePlateRecognition*>(schedulingAlgorithm(0x02));
    if (selectedLicensePlate!=nullptr) {
        selectedLicensePlate->setIsRunning(true);
        // 调用选定对象的findHuManCar函数
        qInfo() << "车牌调度算法抢到===>sn"<<sSn<<selectedLicensePlate;
        selectedLicensePlate->licensePlateNumber(source, lpNumber,plate, currentTime);
    } else {
        qDebug() << "没有可用的LicensePlateRecognition对象可以调度";
        return ;
    }
}

int AlgorithmTaskManage::executeFindHuManCar(const cv::Mat &source, int res,
                                             std::vector<vides_data::ParkingArea> &currentPlate,std::map<int,int>&resMap,QString sSn) {
    
    semaphore.acquire();
    ScopeSemaphoreExit guard([this]() {
        semaphore.release();  // 释放信号量
    });
    auto* selectedHumanDetection = static_cast<HumanDetection*>(schedulingAlgorithm(0x01));
    if (selectedHumanDetection!=nullptr) {
        selectedHumanDetection->setIsRunning(true);
        // 调用选定对象的findHuManCar函数
        qInfo() << "人形调度算法抢到===>sn"<<sSn<<"res"<<selectedHumanDetection;
        int detectionResult = selectedHumanDetection->findHuManCar(source, res,resMap, currentPlate);
        return detectionResult;
    } else {
        qDebug() << "没有可用的HumanDetection对象可以调度";
        return -2;
    }
}
