#include "logic.h"
#include "ccritical_res_manager.h"


CCriticalResManager::CCriticalResManager()
{
    for (int i = 1; i <= 19; ++i) {
        mapResList[1UL<<i] = CriticalRes();
    }
}


CCriticalResManager::~CCriticalResManager()
{}

bool CCriticalResManager::Acquire(int iVSMId, const std::vector<int>& vecList)
{
    QMutexLocker l(&mutex);
    for (size_t i = 0; i < vecList.size(); ++i) {
        CriticalRes& res = mapResList.at(vecList[i]);
        if (res.bLocked && iVSMId != res.iOwner) {
            return false;
        }
    }

    for (size_t i = 0; i < vecList.size(); ++i) {
        CriticalRes& res = mapResList.at(vecList[i]);
        if (false == res.bLocked) {
            res.bLocked = true;
            res.iOwner = iVSMId;
        }
    }
    return true;
}

bool CCriticalResManager::Acquire(int iVSMId, uint resId)
{
    QMutexLocker l(&mutex);
    for (auto iter = mapResList.cbegin(); iter != mapResList.cend(); ++iter) {
        if (resId & iter->first) {
            if (iter->second.bLocked && iVSMId != iter->second.iOwner) {
                return false;
            }
        }
    }

    for (auto iter = mapResList.begin(); iter != mapResList.end(); ++iter) {
        if (resId & iter->first) {
            if (!iter->second.bLocked) {
                iter->second.bLocked = true;
                iter->second.iOwner = iVSMId;
            }
        }
    }

    MqDebug() << "----------Acquire" << resId << " SM:" << iVSMId;
    return true;
}

bool CCriticalResManager::CanAcquire(int iVSMId, const std::vector<int>& vecList)
{
    QMutexLocker l(&mutex);
    for (size_t i = 0; i < vecList.size(); ++i) {
        CriticalRes& res = mapResList.at(vecList[i]);
        if (res.bLocked && iVSMId != res.iOwner) {
            return false;
        }
    }

    return true;
}

bool CCriticalResManager::CanAcquire(int iVSMId, uint resId)
{
    QMutexLocker l(&mutex);
    for (auto iter = mapResList.cbegin(); iter != mapResList.cend(); ++iter) {
        if (resId & iter->first) {
             if (iter->second.bLocked && iVSMId != iter->second.iOwner) {
                return false;
            } 
        }
    }
   
    return true;
}

bool CCriticalResManager::NotAcquired(int iVSMID, uint resId)
{
    //HACK:测试功能
    return false;
    QMutexLocker l(&mutex);
    for (auto iter = mapResList.cbegin(); iter != mapResList.cend(); ++iter)
    {
        if (resId & iter->first)
        {
            if (!iter->second.bLocked)
            {
                return true;
            }
            if (iter->second.bLocked && iVSMID != iter->second.iOwner)
            {
                return true;
            }
        }
    }

    return false;
}

bool CCriticalResManager::Release(const std::vector<int>& vecList)
{
    QMutexLocker l(&mutex);
    for (size_t i = 0; i < vecList.size(); ++i) {
        CriticalRes& res = mapResList.at(vecList[i]);
        res.bLocked = false;
        res.iOwner = 0;
    }

    return true;
}

void CCriticalResManager::Release(int iVsmId)
{
    QMutexLocker l(&mutex);
    for (auto iter = mapResList.begin(); iter != mapResList.end(); ++iter) {
        if (iter->second.bLocked && iter->second.iOwner==iVsmId) {
            iter->second.bLocked = false;
            iter->second.iOwner = 0;
        }
    }
}

bool CCriticalResManager::ReleaseForce(uint resId)
{
    QMutexLocker l(&mutex);
    for (auto iter = mapResList.begin(); iter != mapResList.end(); ++iter) {
        if (resId & iter->first) {
            iter->second.bLocked = false;
            iter->second.iOwner = 0;
        }
    }

    MqDebug() << "----------Release" << resId;
    return true;
}

bool CCriticalResManager::Release(int iVsmId, uint resId)
{
    QMutexLocker l(&mutex);
    for (auto iter = mapResList.begin(); iter != mapResList.end(); ++iter) {
        if (resId & iter->first) {
            if (iter->second.bLocked 
                && (iVsmId == iter->second.iOwner || iVsmId == 0)) {
                iter->second.bLocked = false;
                iter->second.iOwner = 0;
            }
        }
    }

    return true;
}

bool CCriticalResManager::IsAcquired(int iVSMId, uint resId)
{
    QMutexLocker l(&mutex);
    for (auto iter = mapResList.cbegin(); iter != mapResList.cend(); ++iter) {
        if (resId & iter->first) {
            if (!iter->second.bLocked) return false;
            if (iter->second.bLocked && iVSMId == iter->second.iOwner) {
                return false;
            }
        }
    }

    return true;
}
