#include "include.h"
#pragma comment(lib, "wbemuuid.lib")

Napi::Value mem_used_size(const Napi::CallbackInfo& info){
        Napi::Env env = info.Env();

    for (Hardware hardware:computer->getHardware()){
        if(hardware.getHardwareType()==HardwareType::Memory){
            for(Sensor sen:hardware.getSensors()){
                char *name=sen.getName();
                    if(sen.getType()==SensorType::Data && (strcmp(name, "Memory Used")==0)){
                    delete[] name;
                       return Napi::Number::New(env, sen.getValue()); 
                    }
                    delete[] name;
                }
        }
    }
        return env.Null();

}
Napi::Value vmem_used_size(const Napi::CallbackInfo& info){
        Napi::Env env = info.Env();

    for (Hardware hardware:computer->getHardware()){
        if(hardware.getHardwareType()==HardwareType::Memory){
            for(Sensor sen:hardware.getSensors()){
                char *name=sen.getName();
                    if(sen.getType()==SensorType::Data && (strcmp(name, "Virtual Memory Used")==0)){
                    delete[] name;
                       return Napi::Number::New(env, sen.getValue()); 
                    }
                    delete[] name;
                }
        }
    }
        return env.Null();

}
Napi::Value mem_free_size(const Napi::CallbackInfo& info){
        Napi::Env env = info.Env();

    for (Hardware hardware:computer->getHardware()){
        if(hardware.getHardwareType()==HardwareType::Memory){
            for(Sensor sen:hardware.getSensors()){
                char *name=sen.getName();
                    if(sen.getType()==SensorType::Data && (strcmp(name, "Memory Available")==0)){
                    delete[] name;
                       return Napi::Number::New(env, sen.getValue()); 
                    }
                    delete[] name;
                }
        }
    }
        return env.Null();

}
Napi::Value vmem_free_size(const Napi::CallbackInfo& info){
        Napi::Env env = info.Env();

    for (Hardware hardware:computer->getHardware()){
        if(hardware.getHardwareType()==HardwareType::Memory){
            for(Sensor sen:hardware.getSensors()){
                char *name=sen.getName();
                    if(sen.getType()==SensorType::Data && (strcmp(name, "Virtual Memory Available")==0)){
                    delete[] name;
                       return Napi::Number::New(env, sen.getValue()); 
                    }
                    delete[] name;
                }
        }
    }
        return env.Null();

}

Napi::Value mem_clock(const Napi::CallbackInfo& info){
        Napi::Env env = info.Env();

    for (Hardware hardware:computer->getHardware()){
        if(hardware.getHardwareType()==HardwareType::Memory){
            for(Sensor sen:hardware.getSensors()){
                    if(sen.getType()==SensorType::Clock){
                       return Napi::Number::New(env, sen.getValue()); 
                    }
                }
        }
    }
    return env.Null();
}



Napi::Value mem_size(const Napi::CallbackInfo& info) {
        Napi::Env env = info.Env();
    HRESULT hr;
    IWbemLocator* pLoc = nullptr;
    hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    IWbemServices* pSvc = nullptr;
    hr = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), nullptr, nullptr, 0, NULL, 0, 0, &pSvc);
    hr = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);

    // 查询总容量
    IEnumWbemClassObject* pEnumerator = nullptr;
    hr = pSvc->ExecQuery(_bstr_t(L"WQL"), _bstr_t(L"SELECT Capacity FROM Win32_PhysicalMemory"), WBEM_FLAG_FORWARD_ONLY, nullptr, &pEnumerator);
    
    ULONG uReturn = 0;
    IWbemClassObject* pObj = nullptr;
    DWORD totalCapacity = 0;
    while (pEnumerator->Next(WBEM_INFINITE, 1, &pObj, &uReturn) == S_OK) {
        VARIANT vtCapacity;
        hr = pObj->Get(L"Capacity", 0, &vtCapacity, nullptr, nullptr);
        totalCapacity += vtCapacity.ullVal / (1024 * 1024 * 1024); // 转换为GB
        VariantClear(&vtCapacity);
        pObj->Release();
    }

    pSvc->Release();
    pLoc->Release();
    return Napi::Number::New(env, totalCapacity);

}
Napi::String mem_name(const Napi::CallbackInfo& info) {
      Napi::Env env = info.Env();

    for (Hardware hardware:computer->getHardware()){
        if(hardware.getHardwareType()==HardwareType::Memory){
            return Napi::String::New(env, hardware.Name()); 
                    
        }
    }
    return Napi::String::New(env, "");

}