//
// 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_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 "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/bs/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;
    }

    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;

  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)
    {
        pci.FillInfo(device, PCI_FILL_IDENT | PCI_FILL_CLASS);

        // Skip non-GPU devices
        switch (device->device_class)
        {
            case PCI_CLASS_DISPLAY_VGA:
            case PCI_CLASS_DISPLAY_XGA:
            case PCI_CLASS_DISPLAY_3D:
                break;
            default:
                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;

        devices->push_back(info);
    }

    pci.Cleanup(access);

    return true;
}
}
