//
// Copyright (c) 2013-2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// SystemInfo.cpp: implementation of the system-agnostic parts of SystemInfo.h

#include "gpu_info_util/SystemInfo.h"

#include <cstring>
#include <sstream>

#include "common/debug.h"
#include "common/string_utils.h"

namespace angle
{

bool IsAMD(VendorID vendorId)
{
    return vendorId == kVendorID_AMD;
}

bool IsIntel(VendorID vendorId)
{
    return vendorId == kVendorID_Intel;
}

bool IsNvidia(VendorID vendorId)
{
    return vendorId == kVendorID_Nvidia;
}

bool IsQualcomm(VendorID vendorId)
{
    return vendorId == kVendorID_Qualcomm;
}

bool ParseAMDBrahmaDriverVersion(const std::string &content, std::string *version)
{
    const size_t begin = content.find_first_of("0123456789");
    if (begin == std::string::npos)
    {
        return false;
    }

    const size_t end = content.find_first_not_of("0123456789.", begin);
    if (end == std::string::npos)
    {
        *version = content.substr(begin);
    }
    else
    {
        *version = content.substr(begin, end - begin);
    }
    return true;
}

bool ParseAMDCatalystDriverVersion(const std::string &content, std::string *version)
{
    std::istringstream stream(content);

    std::string line;
    while (std::getline(stream, line))
    {
        static const char kReleaseVersion[] = "ReleaseVersion=";
        if (line.compare(0, std::strlen(kReleaseVersion), kReleaseVersion) != 0)
        {
            continue;
        }

        if (ParseAMDBrahmaDriverVersion(line, version))
        {
            return true;
        }
    }
    return false;
}

bool ParseMacMachineModel(const std::string &identifier,
                          std::string *type,
                          int32_t *major,
                          int32_t *minor)
{
    size_t numberLoc = identifier.find_first_of("0123456789");
    if (numberLoc == std::string::npos)
    {
        return false;
    }

    size_t commaLoc = identifier.find(',', numberLoc);
    if (commaLoc == std::string::npos || commaLoc >= identifier.size())
    {
        return false;
    }

    const char *numberPtr = &identifier[numberLoc];
    const char *commaPtr  = &identifier[commaLoc + 1];
    char *endPtr          = nullptr;

    int32_t majorTmp = std::strtol(numberPtr, &endPtr, 10);
    if (endPtr == numberPtr)
    {
        return false;
    }

    int32_t minorTmp = std::strtol(commaPtr, &endPtr, 10);
    if (endPtr == commaPtr)
    {
        return false;
    }

    *major = majorTmp;
    *minor = minorTmp;
    *type  = identifier.substr(0, numberLoc);

    return true;
}

bool CMDeviceIDToDeviceAndVendorID(const std::string &id, uint32_t *vendorId, uint32_t *deviceId)
{
    unsigned int vendor = 0;
    unsigned int device = 0;

    bool success = id.length() >= 21 && HexStringToUInt(id.substr(8, 4), &vendor) &&
                   HexStringToUInt(id.substr(17, 4), &device);

    *vendorId = vendor;
    *deviceId = device;
    return success;
}

void FindPrimaryGPU(SystemInfo *info)
{
    ASSERT(!info->gpus.empty());

    // On dual-GPU systems we assume the non-Intel GPU is the primary one.
    int primary   = 0;
    bool hasIntel = false;
    for (size_t i = 0; i < info->gpus.size(); ++i)
    {
        if (IsIntel(info->gpus[i].vendorId))
        {
            hasIntel = true;
        }
        if (IsIntel(info->gpus[primary].vendorId))
        {
            primary = static_cast<int>(i);
        }
    }

    // Assume that a combination of AMD or Nvidia with Intel means Optimus or AMD Switchable
    info->primaryGPUIndex = primary;
    info->isOptimus       = hasIntel && IsNvidia(info->gpus[primary].vendorId);
    info->isAMDSwitchable = hasIntel && IsAMD(info->gpus[primary].vendorId);
}

}  // namespace angle
