#include "SerialNumber.h"

#ifdef _WIN32
    #include <windows.h>
#elif __linux__
    #include <unistd.h>
#elif __APPLE__
    #include <sys/sysctl.h>
#endif

std::string GetCPUSerialNumber() {
    std::string cpuSerialNumber = "";

#ifdef _WIN32
    // 使用Windows API获取CPU信息
    char buffer[1024];
    DWORD bufferSize = sizeof(buffer);
    if (GetPrivateProfileStringA("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "ProcessorNameString", "", buffer, bufferSize, "HARDWARE\\DESCRIPTION\\System"))
    {
        cpuSerialNumber = buffer;
    }
#elif __linux__
    // 使用Linux特定命令获取CPU信息
    char buffer[256];
    FILE* fp = popen("cat /proc/cpuinfo | grep 'serial number' | uniq | awk '{print $NF}'", "r");
    if (fp != nullptr)
    {
        fgets(buffer, sizeof(buffer), fp);
        pclose(fp);
        cpuSerialNumber = buffer;
    }
#elif __APPLE__
    // 使用macOS特定API获取CPU信息
    size_t len = 0;
    sysctlbyname("machdep.cpu.brand_string", nullptr, &len, nullptr, 0);
    char* buffer = new char[len];
    sysctlbyname("machdep.cpu.brand_string", buffer, &len, nullptr, 0);
    cpuSerialNumber = buffer;
    delete[] buffer;
#endif

    return cpuSerialNumber;
}

std::string GetHardDiskSerialNumber() {
    std::string hardDiskSerialNumber = "";

#ifdef _WIN32
    // 使用Windows API获取硬盘信息
    DWORD volumeSerialNumber;
    GetVolumeInformation("C:\\", nullptr, 0, &volumeSerialNumber, nullptr, nullptr, nullptr, 0);
    hardDiskSerialNumber = std::to_string(volumeSerialNumber);
#elif __linux__
    // 使用Linux特定命令获取硬盘信息
    char buffer[256];
    FILE* fp = popen("lsblk -d -n -o serial /dev/sda", "r");
    if (fp != nullptr)
    {
        fgets(buffer, sizeof(buffer), fp);
        pclose(fp);
        hardDiskSerialNumber = buffer;
    }
#elif __APPLE__
    // 使用macOS特定API获取硬盘信息
    char buffer[256];
    FILE* fp = popen("system_profiler SPNVMeDataType | grep 'Serial Number:' | awk '{print $NF}'", "r");
    if (fp != nullptr)
    {
        fgets(buffer, sizeof(buffer), fp);
        pclose(fp);
        hardDiskSerialNumber = buffer;
    }
#endif

    return hardDiskSerialNumber;
}