//
// Copyright 2013 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_libpci.cpp: implementation of the libPCI-specific parts of SystemInfo.h

#include "gpu_info_util/SystemInfo_internal.h"

#include <dlfcn.h>
#include <pci/pci.h>
#include <unistd.h>
#include <fstream>

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

#if !defined(GPU_INFO_USE_LIBPCI)
#    error SystemInfo_libpci.cpp compiled without GPU_INFO_USE_LIBPCI
#endif

namespace angle
{

namespace
{

struct LibPCI : private angle::NonCopyable
{
    LibPCI()
    {
        if (access("/sys/bus/pci/", F_OK) != 0 && access("/sys/bus/pci_express/", F_OK) != 0)
        {
            return;
        }

        mHandle = dlopen("libpci.so.3", RTLD_LAZY);

        if (mHandle == nullptr)
        {
            mHandle = dlopen("libpci.so", RTLD_LAZY);
        }

        if (mHandle == nullptr)
        {
            return;
        }

        mValid =
            (Alloc = reinterpret_cast<decltype(Alloc)>(dlsym(mHandle, "pci_alloc"))) != nullptr &&
            (Init = reinterpret_cast<decltype(Init)>(dlsym(mHandle, "pci_init"))) != nullptr &&
            (Cleanup = reinterpret_cast<decltype(Cleanup)>(dlsym(mHandle, "pci_cleanup"))) !=
                nullptr &&
            (ScanBus = reinterpret_cast<decltype(ScanBus)>(dlsym(mHandle, "pci_scan_bus"))) !=
                nullptr &&
            (FillInfo = reinterpret_cast<decltype(FillInfo)>(dlsym(mHandle, "pci_fill_info"))) !=
                nullptr &&
            (LookupName = reinterpret_cast<decltype(LookupName)>(
                 dlsym(mHandle, "pci_lookup_name"))) != nullptr &&
            (PCIReadByte = reinterpret_cast<decltype(PCIReadByte)>(
                 dlsym(mHandle, "pci_read_byte"))) != nullptr;
    }

    bool IsValid() const { return mValid; }

    ~LibPCI()
    {
        if (mHandle != nullptr)
        {
            dlclose(mHandle);
        }
    }

    decltype(&::pci_alloc) Alloc            = nullptr;
    decltype(&::pci_init) Init              = nullptr;
    decltype(&::pci_cleanup) Cleanup        = nullptr;
    decltype(&::pci_scan_bus) ScanBus       = nullptr;
    decltype(&::pci_fill_info) FillInfo     = nullptr;
    decltype(&::pci_lookup_name) LookupName = nullptr;
    decltype(&::pci_read_byte) PCIReadByte  = nullptr;

    uint8_t GetRevisionId(pci_dev *device)
    {
        char revision_path[100];
        snprintf(revision_path, sizeof(revision_path),
                 "/sys/bus/pci/devices/%04x:%02x:%02x.%d/revision", device->domain, device->bus,
                 device->dev, device->func);

        std::ifstream file(revision_path);
        if (file.is_open())
        {
            uint8_t rev;
            if (file >> std::hex >> rev)
            {
                return rev;
            }
        }

        return PCIReadByte(device, PCI_REVISION_ID);
    }

  private:
    void *mHandle = nullptr;
    bool mValid   = false;
};

}  // anonymous namespace

// Adds an entry per PCI GPU found and fills the device and vendor ID.
bool GetPCIDevicesWithLibPCI(std::vector<GPUDeviceInfo> *devices)
{
    LibPCI pci;
    if (!pci.IsValid())
    {
        return false;
    }

    pci_access *access = pci.Alloc();
    ASSERT(access != nullptr);
    pci.Init(access);
    pci.ScanBus(access);

    for (pci_dev *device = access->devices; device != nullptr; device = device->next)
    {
#if PCI_LIB_VERSION >= 0x030800
        pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_CLASS_EXT);
#else
        pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS);
#endif

        // Skip non-GPU devices
        if (device->device_class >> 8 != PCI_BASE_CLASS_DISPLAY)
        {
            continue;
        }

        // Skip unknown devices
        if (device->vendor_id == 0 || device->device_id == 0)
        {
            continue;
        }

        GPUDeviceInfo info;
        info.vendorId   = device->vendor_id;
        info.deviceId   = device->device_id;
#if PCI_LIB_VERSION >= 0x030800
        info.revisionId = device->rev_id;
#else
        info.revisionId = pci.GetRevisionId(device);
#endif

        devices->push_back(info);
    }

    pci.Cleanup(access);

    return true;
}
}  // namespace angle
