#pragma once

#include "error_messages.hpp"
#include "managed_store_types.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"

#include <unistd.h>

#include <app.hpp>
#include <boost/container/flat_set.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/message.hpp>

namespace redfish
{

const std::string portObjPathDir = "/xyz/openbmc_project/metric/bmc0/port/";

inline void populatePortInfo(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                      const std::string& objectPath)
{
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<double>(
        "xyz.openbmc_project.Metric", objectPath,
        "xyz.openbmc_project.Metric.Port", "CurrentSpeedGbps", requestContext,
        [asyncResp](const boost::system::error_code ec, const double& speed) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBus error getting port speed";
            messages::internalError(asyncResp->res);
            return;
        }

        asyncResp->res.jsonValue["CurrentSpeedGbps"] = speed;
        });

    dbus_utils::getProperty<std::string>(
        "xyz.openbmc_project.Metric", objectPath,
        "xyz.openbmc_project.Metric.Port", "LinkState", requestContext,
        [asyncResp](const boost::system::error_code ec,
                    const std::string& linkState) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBus error getting port link state";
            messages::internalError(asyncResp->res);
            return;
        }

        // If somehow we get a different LinkState, then dont report it
        if (linkState == "xyz.openbmc_project.Metric.LinkState.Disabled")
        {
            asyncResp->res.jsonValue["LinkState"] = "Disabled";
        }
        else if (linkState == "xyz.openbmc_project.Metric.LinkState.Enabled")
        {
            asyncResp->res.jsonValue["LinkState"] = "Enabled";
        }
        });

    dbus_utils::getProperty<std::string>(
        "xyz.openbmc_project.Metric", objectPath,
        "xyz.openbmc_project.Metric.Port", "LinkStatus", requestContext,
        [asyncResp](const boost::system::error_code ec,
                    const std::string& linkStatus) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBus error getting port link status";
            messages::internalError(asyncResp->res);
            return;
        }

        if (linkStatus == "xyz.openbmc_project.Metric.LinkStatus.Down")
        {
            asyncResp->res.jsonValue["LinkStatus"] = "Down";
        }
        else if (linkStatus == "xyz.openbmc_project.Metric.LinkStatus.Up")
        {
            asyncResp->res.jsonValue["LinkStatus"] = "Up";
        }
        });
}

inline void handleDedicatedNetworkPortsGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& portId)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    asyncResp->res.jsonValue["@odata.type"] = "#Port.v1_7_0.Port";
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/" + portId;
    asyncResp->res.jsonValue["Name"] = "Network Port";

    asyncResp->res.jsonValue["Id"] = portId;
    asyncResp->res.jsonValue["Description"] = "Network Port information";

    asyncResp->res.jsonValue["Metrics"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/" + portId + "/Metrics";

    populatePortInfo(asyncResp, portObjPathDir + portId);
}

inline std::string getPortIdFromObjectPath(const std::string& objPath)
{
    return sdbusplus::message::object_path(objPath).filename();
}

inline void handleDedicatedNetworkPortsCollectionGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    asyncResp->res.jsonValue["@odata.type"] = "#PortCollection.PortCollection";
    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/DedicatedNetworkPorts";
    asyncResp->res.jsonValue["Name"] = "Dedicated Network Ports Collection";
    asyncResp->res.jsonValue["Description"] =
        "Collection of Dedicated Network Ports for this Manager";

    asyncResp->res.jsonValue["@odata.id"] =
        "/redfish/v1/Managers/bmc/DedicatedNetworkPorts";

    asyncResp->res.jsonValue["Members"] = nlohmann::json::array();

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<std::vector<std::string>>(
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/metric/bmc0/port",
        "xyz.openbmc_project.Association", "endpoints", requestContext,
        [asyncResp](const boost::system::error_code ec,
                    const std::vector<std::string>& endpoints) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "DBus error getting port association endpoints";
            return;
        }

        for (const std::string& endpoint : endpoints)
        {
            nlohmann::json portInterface;
            portInterface["@odata.id"] =
                "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/" +
                getPortIdFromObjectPath(endpoint);

            asyncResp->res.jsonValue["Members"].push_back(portInterface);
        }
        asyncResp->res.jsonValue["Members@odata.count"] = endpoints.size();
        });
}

inline void requestPortsRoutes(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/DedicatedNetworkPorts")
        .privileges(redfish::privileges::getPortCollection)
        .methods(boost::beast::http::verb::get)(std::bind_front(
            handleDedicatedNetworkPortsCollectionGet, std::ref(app)));
    BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/DedicatedNetworkPorts/<str>")
        .privileges(redfish::privileges::getPort)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleDedicatedNetworkPortsGet, std::ref(app)));
}

} // namespace redfish
