#include "rde_match_handler.hpp"

#include "util/mctp_setup.hpp"

#include <sdbusplus/unpack_properties.hpp>
#include <stdplus/print.hpp>

#include <format>

using DbusVariant = std::variant<std::string, uint64_t, uint32_t, uint16_t,
                                 uint8_t, sdbusplus::message::object_path>;
using ChangedPropertiesType = std::vector<std::pair<std::string, DbusVariant>>;

RdeMatchHandler::RdeMatchHandler(int socketFd) : fd(socketFd)
{}

RdeMatchHandler::~RdeMatchHandler()
{}

int RdeMatchHandler::initiateDiscovery(const int& fd, const std::string& udevId,
                                       const int& netId)
{
    int rc = 0;
    // Begin Base Discovery
    stdplus::print(stderr, "Initiating PLDM Discovery...\n");

    // TODO(@harshtya): Add discovery calls
    // TODO(@harshtya): Remove the log below after discovery calls
    stdplus::print(stderr, "Call arguments: {}, {}, {}\n", fd, udevId, netId);
    if (rc)
    {
        stdplus::print(stderr,
                       "Failure in Base Discovery with error code: {}\n", rc);
        return rc;
    }
    return rc;
}

void RdeMatchHandler::scanForExistingDevices(
    const int& fd, sdbusplus::asio::object_server& objectServer,
    const std::string& prefixPath,
    std::shared_ptr<sdbusplus::asio::connection>& systemBus)
{
    using propertyMap =
        std::vector<std::pair<std::string, std::vector<std::string>>>;
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Configuration.RdeSatelliteController"};
    using DBusProperties = std::vector<std::pair<std::string, DbusVariant>>;

    systemBus->async_method_call_timed(
        [this, &fd, &systemBus, &objectServer, &prefixPath](
            const boost::system::error_code& ec,
            const std::vector<std::pair<std::string, propertyMap>>& subtree) {
        if (ec)
        {
            stdplus::print(
                stderr,
                "Failed to scan existing RDE object paths with error msg: {}\n",
                ec.message());
            return;
        }
        if (subtree.empty())
        {
            stdplus::print(
                stderr,
                "RDE Device scan empty. "
                "No instances found while parsing Entity Manager tree\n");
            return;
        }
        for (const auto& [objPath, services] : subtree)
        {
            for (const auto& service : services)
            {
                systemBus->async_method_call_timed(
                    [this, &fd, &objectServer, &prefixPath,
                     objPath](const boost::system::error_code& errorCode,
                              const DBusProperties& properties) {
                    if (errorCode)
                    {
                        stdplus::print(
                            stderr,
                            "Scanning RDE Devices failed."
                            " Error in DBus response  ec: {} and msg: {}\n",
                            errorCode.value(), errorCode.message());
                        return;
                    }
                    std::string vendorId;
                    std::string udevId;
                    std::string port;
                    const bool success = sdbusplus::unpackPropertiesNoThrow(
                        [](const sdbusplus::UnpackErrorReason reason,
                           const std::string& property) {
                        stdplus::print(
                            stderr,
                            "Error unpacking the property: {} with error: {}\n",
                            property, static_cast<int>(reason));
                    },
                        properties, "VID", vendorId, "USBPORT", port, "UDEVID",
                        udevId);
                    if (success)
                    {
                        if (vendorId.empty() || port.empty() || udevId.empty())
                        {
                            stdplus::print(
                                stderr,
                                "RDE Device scan failed due to matcher not"
                                "having the required properties\n");
                            return;
                        }
                        // Do PLDM Setup
                        rdeSetup(fd, objectServer, std::string(objPath), port,
                                 udevId, vendorId, prefixPath);
                    }
                    else
                    {
                        stdplus::print(
                            stderr,
                            "RDE device scan failed due to error in parsing"
                            "properties\n");
                    }
                },
                    service.first, objPath, "org.freedesktop.DBus.Properties",
                    "GetAll", /*timeout in usec*/ 90000000,
                    "xyz.openbmc_project.Configuration.RdeSatelliteController");
            }
        }
    },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree",
        /*timeout in usec*/ 90000000, "/xyz/openbmc_project/inventory", 0,
        interfaces);
}

std::unique_ptr<sdbusplus::bus::match_t> RdeMatchHandler::handleMatchAdd(
    std::shared_ptr<sdbusplus::asio::connection>& systemBus,
    sdbusplus::asio::object_server& objectServer, const std::string& prefixPath,
    const int& fd)
{
    return std::make_unique<sdbusplus::bus::match_t>(
        *systemBus, sdbusplus::bus::match::rules::interfacesAdded(),
        [this, &objectServer, &prefixPath, &systemBus,
         &fd](sdbusplus::message_t& reply) {
        sdbusplus::message::object_path changedObject;
        reply.read(changedObject);

        std::vector<std::pair<std::string, ChangedPropertiesType>>
            changedInterfaces;
        reply.read(changedInterfaces);

        std::string vendorId;
        std::string udevId;
        std::string port;
        for (const auto& [changedInterface, changedProps] : changedInterfaces)
        {
            if (changedInterface !=
                "xyz.openbmc_project.Configuration.RdeSatelliteController")
            {
                continue;
            }

            if (DEBUG)
            {
                stdplus::print(stderr, "New device detected: {}\n",
                               std::string(changedObject));
            }

            for (auto& [key, value] : changedProps)
            {
                if (key == "VID")
                {
                    vendorId = std::get<std::string>(value);
                }
                else if (key == "USBPORT")
                {
                    port = std::get<std::string>(value);
                }
                else if (key == "UDEVID")
                {
                    udevId = std::get<std::string>(value);
                }
            }

            if (vendorId.empty() || port.empty() || udevId.empty())
            {
                stdplus::print(stderr,
                               "Matcher does not have required properties\n");
                return;
            }

            // TODO(@harshtya): Call RDE Setup here
        }
    });
}

std::unique_ptr<sdbusplus::bus::match_t> RdeMatchHandler::handleMatchRemove(
    std::shared_ptr<sdbusplus::asio::connection>& systemBus,
    sdbusplus::asio::object_server& objectServer)
{
    return std::make_unique<sdbusplus::bus::match_t>(
        *systemBus, sdbusplus::bus::match::rules::interfacesRemoved(),
        [this, &objectServer](sdbusplus::message_t& reply) {
        sdbusplus::message::object_path changedObject;
        std::vector<std::string> interfacesRemoved;
        reply.read(changedObject, interfacesRemoved);

        auto it = deviceToDbusIntfMap.find(std::string(changedObject));
        if (it != deviceToDbusIntfMap.end())
        {
            std::shared_ptr<sdbusplus::asio::dbus_interface> iface = it->second;
            auto removed = objectServer.remove_interface(iface);
            stdplus::print(stderr, "Removed RDE Device from tree: {}\n",
                           removed);
            deviceToDbusIntfMap.erase(std::string(changedObject));
            auto it = objectPathToDeviceIdMap.find(std::string(changedObject));
            if (it != objectPathToDeviceIdMap.end())
            {
                cleanupMctpLink(it->second);
                // TODO (@harshtya): clean up the Rde device from maps
                // TODO (@harshtya): clean up the dictionaries
                objectPathToDeviceIdMap.erase(std::string(changedObject));
                deviceToNetIdMap.erase(it->second);
            }
        }
    });
}

void RdeMatchHandler::triggerMatcher()
{
    boost::asio::io_context io;
    std::shared_ptr<sdbusplus::asio::connection> systemBus =
        std::make_shared<sdbusplus::asio::connection>(io);
    sdbusplus::asio::object_server objectServer(systemBus, true);
    objectServer.add_manager("/xyz/openbmc_project/rde_devices");
    std::string prefixPath = "/xyz/openbmc_project/rde_devices/";

    // TODO(@harshtya): Add scan for existing devices

    // Initialize the match handler for interfacesAdded
    auto matchAdd =
        handleMatchAdd(systemBus, objectServer, prefixPath, this->fd);
    // Matcher to monitor for devices removed
    auto matchRemove = handleMatchRemove(systemBus, objectServer);

    systemBus->request_name("xyz.openbmc_project.rdeoperation");
    io.run();
}

int RdeMatchHandler::rdeSetup(const int& fd,
                              sdbusplus::asio::object_server& objectServer,
                              const std::string& changedObject,
                              const std::string& port,
                              const std::string& udevId,
                              const std::string& vendorId,
                              const std::string& prefixPath)
{
    int netId = setupOnePort(port, udevId); // MCTP Setup
    deviceToNetIdMap.emplace(udevId, netId);
    int rc = initiateDiscovery(fd, udevId, netId);
    if (rc)
    {
        stdplus::print(stderr,
                       "PLDM/RDE Discovery failed for device: {}"
                       "and udevId: {} after all retries\n",
                       port, udevId);
        return rc;
    }

    std::string objectPath = std::format("{}{}", prefixPath, udevId);

    if (DEBUG)
    {
        stdplus::print(stderr, "Creating object path for RDE Operation: {}\n ",
                       objectPath);
    }

    std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
        objectServer.add_interface(objectPath, "xyz.openbmc_project.RdeDevice");
    iface->register_property("VID", vendorId,
                             sdbusplus::asio::PropertyPermission::readOnly);
    iface->register_property("USBPORT", port,
                             sdbusplus::asio::PropertyPermission::readOnly);
    iface->register_property("UDEVID", udevId,
                             sdbusplus::asio::PropertyPermission::readOnly);

    // TODO(@harshtya): Add RDE OPeration Handler Dbus method

    iface->initialize();
    deviceToDbusIntfMap.emplace(std::string(changedObject), iface);
    objectPathToDeviceIdMap.emplace(std::string(changedObject), udevId);
    return 0;
}
