/*
// Copyright (c) 2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#include "peci_pcie.hpp"

#include "pciDeviceClass.hpp"
#include "pciVendors.hpp"

#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <sdbusplus/asio/object_server.hpp>

#include <iomanip>
#include <iostream>
#include <set>
#include <sstream>

namespace peci_pcie
{
static boost::container::flat_map<
    int, boost::container::flat_map<
             int, boost::container::flat_map<
                      int, std::shared_ptr<sdbusplus::asio::dbus_interface>>>>
    pcieDeviceDBusMap;

namespace function
{
static constexpr char const* functionTypeName = "FunctionType";
static constexpr char const* deviceClassName = "DeviceClass";
static constexpr char const* vendorIdName = "VendorId";
static constexpr char const* deviceIdName = "DeviceId";
static constexpr char const* classCodeName = "ClassCode";
static constexpr char const* revisionIdName = "RevisionId";
static constexpr char const* subsystemIdName = "SubsystemId";
static constexpr char const* subsystemVendorIdName = "SubsystemVendorId";
} // namespace function
} // namespace peci_pcie

// PECI Client Address Map
static void getClientAddrMap(std::vector<int>& clientAddrs)
{
    for (int i = MIN_CLIENT_ADDR; i <= MAX_CLIENT_ADDR; i++)
    {
        if (peci_Ping(i) == PECI_CC_SUCCESS)
        {
            clientAddrs.push_back(i);
        }
    }
}

static bool isPECIAvailable(void)
{
    std::vector<int> clientAddrs;
    getClientAddrMap(clientAddrs);
    if (clientAddrs.empty())
    {
        return false;
    }
    return true;
}

static bool getDataFromPCIeConfig(const int& clientAddr, const int& bus,
                                  const int& dev, const int& func,
                                  const int& offset, const int& size,
                                  uint32_t& pciData)
{
    // PECI RdPCIConfig() currently only supports 4 byte reads, so adjust
    // the offset and size to get the right data
    static constexpr const int pciReadSize = 4;
    int mod = offset % pciReadSize;
    int pciOffset = offset - mod;
    if (mod + size > pciReadSize)
    {
        return false;
    }

    std::array<uint8_t, pciReadSize> data;
    uint8_t cc;
    int ret = peci_RdPCIConfig(clientAddr,  // CPU Address
                               bus,         // PCI Bus
                               dev,         // PCI Device
                               func,        // PCI Function
                               pciOffset,   // PCI Offset
                               data.data(), // PCI Read Data
                               &cc);        // PECI Completion Code

    if (ret != PECI_CC_SUCCESS || cc != PECI_DEV_CC_SUCCESS)
    {
        return false;
    }

    // Now build the requested data into a single number
    pciData = 0;
    for (int i = mod; i < mod + size; i++)
    {
        pciData |= data[i] << 8 * (i - mod);
    }

    return true;
}

static std::string getStringFromPCIeConfig(const int& clientAddr,
                                           const int& bus, const int& dev,
                                           const int& func, const int& offset,
                                           const int& size)
{
    // Get the requested data
    uint32_t data = 0;
    if (!getDataFromPCIeConfig(clientAddr, bus, dev, func, offset, size, data))
    {
        return std::string();
    }

    // And convert it to a string
    std::stringstream dataStream;
    dataStream << "0x" << std::hex << std::setfill('0') << std::setw(size * 2)
               << data;
    return dataStream.str();
}

static std::string getVendorName(const int& clientAddr, const int& bus,
                                 const int& dev)
{
    static constexpr const int vendorIDOffset = 0x00;
    static constexpr const int vendorIDSize = 2;

    // Get the header type register from function 0
    uint32_t vendorID = 0;
    if (!getDataFromPCIeConfig(clientAddr, bus, dev, 0, vendorIDOffset,
                               vendorIDSize, vendorID))
    {
        return std::string();
    }
    // Get the vendor name or use Other if it doesn't exist
    return pciVendors.try_emplace(vendorID, otherVendor).first->second;
}

static std::string getDeviceClass(const int& clientAddr, const int& bus,
                                  const int& dev, const int& func)
{
    static constexpr const int baseClassOffset = 0x0b;
    static constexpr const int baseClassSize = 1;

    // Get the Device Base Class
    uint32_t baseClass = 0;
    if (!getDataFromPCIeConfig(clientAddr, bus, dev, func, baseClassOffset,
                               baseClassSize, baseClass))
    {
        return std::string();
    }
    // Get the base class name or use Other if it doesn't exist
    return pciDeviceClasses.try_emplace(baseClass, otherClass).first->second;
}

static bool isMultiFunction(const int& clientAddr, const int& bus,
                            const int& dev)
{
    static constexpr const int headerTypeOffset = 0x0e;
    static constexpr const int headerTypeSize = 1;
    static constexpr const int multiFuncBit = 1 << 7;

    // Get the header type register from function 0
    uint32_t headerType = 0;
    if (!getDataFromPCIeConfig(clientAddr, bus, dev, 0, headerTypeOffset,
                               headerTypeSize, headerType))
    {
        return false;
    }
    // Check if it's a multifunction device
    if (headerType & multiFuncBit)
    {
        return true;
    }
    return false;
}

static bool pcieFunctionExists(const int& clientAddr, const int& bus,
                               const int& dev, const int& func)
{
    constexpr const int pciIDOffset = 0;
    constexpr const int pciIDSize = 4;
    uint32_t pciID = 0;
    if (!getDataFromPCIeConfig(clientAddr, bus, dev, func, pciIDOffset,
                               pciIDSize, pciID))
    {
        return false;
    }

    // if VID and DID are all 0s or 1s, then the device doesn't exist
    if (pciID == 0x00000000 || pciID == 0xFFFFFFFF)
    {
        return false;
    }

    return true;
}

static bool pcieDeviceExists(const int& clientAddr, const int& bus,
                             const int& dev)
{
    // Check if this device exists by checking function 0
    return (pcieFunctionExists(clientAddr, bus, dev, 0));
}

static void setPCIeProperty(const int& clientAddr, const int& bus,
                            const int& dev, const std::string& propertyName,
                            const std::string& propertyValue)
{
    std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
        peci_pcie::pcieDeviceDBusMap[clientAddr][bus][dev];

    if (iface->is_initialized())
    {
        iface->set_property(propertyName, propertyValue);
    }
    else
    {
        iface->register_property(propertyName, propertyValue);
    }
}

static void setDefaultPCIeFunctionProperties(const int& clientAddr,
                                             const int& bus, const int& dev,
                                             const int& func)
{
    // Set the function-specific properties
    static constexpr const std::array functionProperties{
        peci_pcie::function::functionTypeName,
        peci_pcie::function::deviceClassName,
        peci_pcie::function::vendorIdName,
        peci_pcie::function::deviceIdName,
        peci_pcie::function::classCodeName,
        peci_pcie::function::revisionIdName,
        peci_pcie::function::subsystemIdName,
        peci_pcie::function::subsystemVendorIdName,
    };

    for (const char* name : functionProperties)
    {
        setPCIeProperty(clientAddr, bus, dev,
                        "Function" + std::to_string(func) + std::string(name),
                        std::string());
    }
}

static void setPCIeFunctionProperties(const int& clientAddr, const int& bus,
                                      const int& dev, const int& func)
{
    // Set the function type always to physical for now
    setPCIeProperty(clientAddr, bus, dev,
                    "Function" + std::to_string(func) +
                        std::string(peci_pcie::function::functionTypeName),
                    "Physical");

    // Set the function Device Class
    setPCIeProperty(clientAddr, bus, dev,
                    "Function" + std::to_string(func) +
                        std::string(peci_pcie::function::deviceClassName),
                    getDeviceClass(clientAddr, bus, dev, func));

    // Get PCI Function Properties that come from PCI config with the following
    // offset and size info
    static constexpr const std::array pciConfigInfo{
        std::tuple<const char*, int, int>{peci_pcie::function::vendorIdName, 0,
                                          2},
        std::tuple<const char*, int, int>{peci_pcie::function::deviceIdName, 2,
                                          2},
        std::tuple<const char*, int, int>{peci_pcie::function::classCodeName, 9,
                                          3},
        std::tuple<const char*, int, int>{peci_pcie::function::revisionIdName,
                                          8, 1},
        std::tuple<const char*, int, int>{peci_pcie::function::subsystemIdName,
                                          0x2e, 2},
        std::tuple<const char*, int, int>{
            peci_pcie::function::subsystemVendorIdName, 0x2c, 2}};

    for (const auto& [name, offset, size] : pciConfigInfo)
    {
        setPCIeProperty(
            clientAddr, bus, dev,
            "Function" + std::to_string(func) + std::string(name),
            getStringFromPCIeConfig(clientAddr, bus, dev, func, offset, size));
    }
}

static void setPCIeDeviceProperties(const int& clientAddr, const int& bus,
                                    const int& dev)
{
    // Set the device manufacturer
    setPCIeProperty(clientAddr, bus, dev, "Manufacturer",
                    getVendorName(clientAddr, bus, dev));

    // Set the device type
    constexpr char const* deviceTypeName = "DeviceType";
    if (isMultiFunction(clientAddr, bus, dev))
    {
        setPCIeProperty(clientAddr, bus, dev, deviceTypeName, "MultiFunction");
    }
    else
    {
        setPCIeProperty(clientAddr, bus, dev, deviceTypeName, "SingleFunction");
    }
}

static void updatePCIeDevice(const int& clientAddr, const int& bus,
                             const int& dev)
{
    setPCIeDeviceProperties(clientAddr, bus, dev);

    // Walk through and populate the functions for this device
    for (int func = 0; func < peci_pcie::maxPCIFunctions; func++)
    {
        if (pcieFunctionExists(clientAddr, bus, dev, func))
        {
            // Set the properties for this function
            setPCIeFunctionProperties(clientAddr, bus, dev, func);
        }
        else
        {
            // Set default properties for unused functions
            setDefaultPCIeFunctionProperties(clientAddr, bus, dev, func);
        }
    }
}

static void addPCIeDevice(sdbusplus::asio::object_server& objServer,
                          const int& clientAddr, const int& cpu, const int& bus,
                          const int& dev)
{
    std::string pathName = std::string(peci_pcie::peciPCIePath) + "/S" +
                           std::to_string(cpu) + "B" + std::to_string(bus) +
                           "D" + std::to_string(dev);
    std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
        objServer.add_interface(pathName, peci_pcie::peciPCIeDeviceInterface);
    peci_pcie::pcieDeviceDBusMap[clientAddr][bus][dev] = iface;

    // Update the properties for the new device
    updatePCIeDevice(clientAddr, bus, dev);

    iface->initialize();
}

static void removePCIeDevice(sdbusplus::asio::object_server& objServer,
                             const int& clientAddr, const int& bus,
                             const int& dev)
{
    std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
        peci_pcie::pcieDeviceDBusMap[clientAddr][bus][dev];

    objServer.remove_interface(iface);

    peci_pcie::pcieDeviceDBusMap[clientAddr][bus].erase(dev);
    if (peci_pcie::pcieDeviceDBusMap[clientAddr][bus].empty())
    {
        peci_pcie::pcieDeviceDBusMap[clientAddr].erase(bus);
    }
    if (peci_pcie::pcieDeviceDBusMap[clientAddr].empty())
    {
        peci_pcie::pcieDeviceDBusMap.erase(clientAddr);
    }
}

static bool pcieDeviceInDBusMap(const int& clientAddr, const int& bus,
                                const int& dev)
{
    if (auto clientAddrIt = peci_pcie::pcieDeviceDBusMap.find(clientAddr);
        clientAddrIt != peci_pcie::pcieDeviceDBusMap.end())
    {
        if (auto busIt = clientAddrIt->second.find(bus);
            busIt != clientAddrIt->second.end())
        {
            if (auto devIt = busIt->second.find(dev);
                devIt != busIt->second.end())
            {
                if (devIt->second)
                {
                    return true;
                }
            }
        }
    }
    return false;
}

static void scanPCIeDevice(boost::asio::io_service& io,
                           sdbusplus::asio::object_server& objServer,
                           std::vector<int> clientAddrs, int cpu, int bus,
                           int dev)
{
    if (pcieDeviceExists(clientAddrs[cpu], bus, dev))
    {
        if (pcieDeviceInDBusMap(clientAddrs[cpu], bus, dev))
        {
            // This device is already in D-Bus, so update it
            updatePCIeDevice(clientAddrs[cpu], bus, dev);
        }
        else
        {
            // This device is not in D-Bus, so add it
            addPCIeDevice(objServer, clientAddrs[cpu], cpu, bus, dev);
        }
    }
    else
    {
        // If PECI is not available, then stop scanning
        if (!isPECIAvailable())
        {
            return;
        }

        if (pcieDeviceInDBusMap(clientAddrs[cpu], bus, dev))
        {
            // This device is in D-Bus, so remove it
            removePCIeDevice(objServer, clientAddrs[cpu], bus, dev);
        }
    }

    // PCIe Device scan completed, so move to the next device
    if (++dev >= peci_pcie::maxPCIDevices)
    {
        // All devices scanned, so move to the next bus
        dev = 0;
        if (++bus >= peci_pcie::maxPCIBuses)
        {
            // All buses scanned, so move to the next CPU
            bus = 0;
            if (++cpu >= clientAddrs.size())
            {
                // All CPUs scanned, so we're done
                return;
            }
        }
    }
    boost::asio::post(io, [&io, &objServer, clientAddrs, cpu, bus, dev]() {
        scanPCIeDevice(io, objServer, clientAddrs, cpu, bus, dev);
    });
}

static void peciAvailableCheck(boost::asio::steady_timer& peciWaitTimer,
                               boost::asio::io_service& io,
                               sdbusplus::asio::object_server& objServer)
{
    static bool lastPECIState;
    bool peciAvailable = isPECIAvailable();
    if (peciAvailable && !lastPECIState)
    {
        lastPECIState = true;

        static boost::asio::steady_timer pcieTimeout(io);
        constexpr const int pcieWaitTime = 60;
        pcieTimeout.expires_after(std::chrono::seconds(pcieWaitTime));
        pcieTimeout.async_wait(
            [&io, &objServer](const boost::system::error_code& ec) {
                if (ec)
                {
                    // operation_aborted is expected if timer is canceled
                    // before completion.
                    if (ec != boost::asio::error::operation_aborted)
                    {
                        std::cerr << "PECI PCIe async_wait failed " << ec;
                    }
                    return;
                }
                // get the PECI client address list
                std::vector<int> clientAddrs;
                getClientAddrMap(clientAddrs);
                // scan PCIe starting from CPU 0, Bus 0, Device 0
                scanPCIeDevice(io, objServer, clientAddrs, 0, 0, 0);
            });
    }
    else if (!peciAvailable && lastPECIState)
    {
        lastPECIState = false;
    }

    peciWaitTimer.expires_after(
        std::chrono::seconds(peci_pcie::peciCheckInterval));
    peciWaitTimer.async_wait([&peciWaitTimer, &io,
                              &objServer](const boost::system::error_code& ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled
            // before completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "PECI Available Check async_wait failed " << ec;
            }
            return;
        }
        peciAvailableCheck(peciWaitTimer, io, objServer);
    });
}

int main(int argc, char* argv[])
{
    // setup connection to dbus
    boost::asio::io_service io;
    std::shared_ptr<sdbusplus::asio::connection> conn =
        std::make_shared<sdbusplus::asio::connection>(io);

    // PECI PCIe Object
    conn->request_name(peci_pcie::peciPCIeObject);
    sdbusplus::asio::object_server server =
        sdbusplus::asio::object_server(conn);

    // Start the PECI check loop
    boost::asio::steady_timer peciWaitTimer(
        io, std::chrono::seconds(peci_pcie::peciCheckInterval));
    peciWaitTimer.async_wait([&peciWaitTimer, &io,
                              &server](const boost::system::error_code& ec) {
        if (ec)
        {
            // operation_aborted is expected if timer is canceled
            // before completion.
            if (ec != boost::asio::error::operation_aborted)
            {
                std::cerr << "PECI Available Check async_wait failed " << ec;
            }
            return;
        }
        peciAvailableCheck(peciWaitTimer, io, server);
    });

    io.run();

    return 0;
}
