/*
// Copyright 2024 Google LLC
//
// 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.
*/
#pragma once

#include "app.hpp"
#include "dbus_utility.hpp"
#include "health.hpp"
#include "human_sort.hpp"
#include "managed_store_types.hpp"
#include "openbmc_dbus_rest.hpp"
#include "query.hpp"
#include "redfish_util.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/dbus_utils.hpp"

#include <boost/system/error_code.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/unpack_properties.hpp>
#include <utils/location_utils.hpp>

#include "managed_store.hpp"

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif

namespace redfish
{

constexpr char const* networkAdapterInventoryIntf =
    "xyz.openbmc_project.Inventory.Item.NetworkAdapter";
constexpr char const* portInventoryIntf =
    "xyz.openbmc_project.Inventory.Item.Port";
constexpr char const* inventoryPrefix = "/xyz/openbmc_project/inventory";

#ifdef UNIT_TEST_BUILD
constexpr const char* netSysfsPath = sysfsNetBasePathUT;
#else
constexpr const char* netSysfsPath = "/sys/class/net/";
#endif

// Helper function to read a file and return its contents as a string
static bool readOneLineFile(const std::filesystem::path& filePath,
                            std::string& content)
{
    try
    {
        std::ifstream ifs(filePath);
        if (ifs.is_open() && std::getline(ifs, content))
        {
            ifs.close();
            return true;
        }
    }
    catch (...)
    {}
    return false;
}

// Helper function for convert a string to uint64 type
// if string is invalid, return default val instead
static uint64_t stringToUint64(const std::string_view str, uint64_t defVal = 0)
{
    uint64_t value = defVal;
    std::from_chars(str.begin(), str.end(), value);
    return value;
}

static std::vector<std::string> sysfsGetEtherDevList()
{
    std::vector<std::string> ethList;
    // Loop through the directory looking for redfish log files
    for (const std::filesystem::directory_entry& dirEnt :
         std::filesystem::directory_iterator(netSysfsPath))
    {
        std::string type;
        // ignore non-ethernet device
        if (readOneLineFile(dirEnt.path() / "type", type) &&
            stringToUint64(type) == 1)
        {
            ethList.push_back(dirEnt.path().filename());
        }
    }

    return ethList;
}

static std::vector<std::string> sysfsGetEthAddrList(const std::string& portName)
{
    std::vector<std::string> addrList;
    std::filesystem::path macPath =
        std::filesystem::path(netSysfsPath) / portName / "address";
    std::string mac;
    try
    {
        std::ifstream ifs(macPath);
        if (ifs.is_open())
        {
            while (std::getline(ifs, mac))
            {
                addrList.push_back(std::move(mac));
            }
        }
    }
    catch (...)
    {}
    return addrList;
}

// gsys uses ethtool ETHTOOL_GLINK, which checks IFF_UP and carriers.
// LinkStatus follows the same metrics with LinkState
static std::string sysfsGetLinkState(const std::string& portName)
{
    std::filesystem::path carrierPath =
        std::filesystem::path(netSysfsPath) / portName / "carrier";
    std::filesystem::path ifflagPath =
        std::filesystem::path(netSysfsPath) / portName / "flags";

    std::string flags;
    std::string carrier;
    if (readOneLineFile(ifflagPath, flags) &&
        static_cast<bool>(stringToUint64(flags) | IFF_UP) &&
        readOneLineFile(carrierPath, carrier) && stringToUint64(carrier) == 1)
    {
        return "Enabled";
    }

    return "Disabled";
}

static double sysfsGetSpeedGbps(const std::string& portName)
{
    std::filesystem::path speedPath =
        std::filesystem::path(netSysfsPath) / portName / "speed";
    std::string speed;

    if (readOneLineFile(speedPath, speed))
    {
        return double(stringToUint64(speed)) / 1000;
    }

    return 0;
}

static nlohmann::json sysfsGetNetworkPortMetrics(const std::string& portName)
{
    nlohmann::json metrics;
    std::filesystem::path statPath =
        std::filesystem::path(netSysfsPath) / portName / "statistics";

    std::string carrierChanges;
    std::string rxCrcErrors;
    std::string rxErrors;
    std::string rxDropped;
    std::string rxPackets;
    if (readOneLineFile(std::filesystem::path(netSysfsPath) / portName /
                            "carrier_changes",
                        carrierChanges))
    {
        metrics["CarrierChanges"] = stringToUint64(
            carrierChanges, std::numeric_limits<uint64_t>::max());
    }
    if (readOneLineFile(statPath / "rx_crc_errors", rxCrcErrors))
    {
        metrics["RXCRCErrors"] =
            stringToUint64(rxCrcErrors, std::numeric_limits<uint64_t>::max());
    }
    if (readOneLineFile(statPath / "rx_errors", rxErrors))
    {
        metrics["RXErrors"] =
            stringToUint64(rxErrors, std::numeric_limits<uint64_t>::max());
    }
    if (readOneLineFile(statPath / "rx_dropped", rxDropped))
    {
        metrics["ReceivedPacketsDropped"] =
            stringToUint64(rxDropped, std::numeric_limits<uint64_t>::max());
    }
    if (readOneLineFile(statPath / "rx_packets", rxPackets))
    {
        metrics["ReceivedPackets"] = stringToUint64(rxPackets, 0);
    }

    return metrics;
}

template <typename Func, typename... Args>
auto handleChassisNetworkAdapterCommon(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string chassisId, Func funcSysfs, Func funcDBus, Args... args)
    -> decltype(funcSysfs(asyncResp, chassisId, args...),
                funcDBus(asyncResp, chassisId, args...))
{
    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
    {
        return;
    }

    managedStore::ManagedObjectStoreContext context(asyncResp);

    dbus_utils::getProperty<std::string>(
        "xyz.openbmc_project.EntityManager",
        "/xyz/openbmc_project/inventory/system/board/" + chassisId + "/BmcNet",
        "xyz.openbmc_project.Configuration.BmcNet", "Name", context,
        [asyncResp, chassisId, funcSysfs, funcDBus,
         args...](const boost::system::error_code& ec2,
                  const std::string& bmcNetName) {
        if (ec2 || bmcNetName != "BmcNet")
        {
            // non-bmc chassis
            funcDBus(asyncResp, chassisId, args...);
        }
        else
        {
            // bmc chassis
            funcSysfs(asyncResp, chassisId, args...);
        }
    });
}

inline void handleChassisNetworkAdapterCollectionGetSysfs(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId)
{
    /**
     * Functions triggers appropriate requests
     */
    asyncResp->res.jsonValue["@odata.type"] =
        "#NetworkAdapterCollection.NetworkAdapterCollection";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "NetworkAdapters");
    asyncResp->res.jsonValue["Name"] =
        "Network adapter Collection for chassis bmc";
    nlohmann::json& members = asyncResp->res.jsonValue["Members"];
    members = nlohmann::json::array();
    nlohmann::json::object_t member;
    member["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "NetworkAdapters", "0");
    members.push_back(std::move(member));
    asyncResp->res.jsonValue["Members@odata.count"] = members.size();
}
// Chassis NetworkAdapters, this URL will show all the NetworkAdapterCollection
// information
inline void handleChassisNetworkAdapterCollectionGetDBus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId)
{
    // mapper call lambda
    constexpr std::array<std::string_view, 2> interfaces = {
        "xyz.openbmc_project.Inventory.Item.Board",
        "xyz.openbmc_project.Inventory.Item.Chassis"};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        inventoryPrefix, 0, interfaces, requestContext,
        [asyncResp, chassisId, requestContext](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            if (ec == boost::system::errc::host_unreachable)
            {
                messages::resourceNotFound(asyncResp->res, "Chassis",
                                           chassisId);
                return;
            }
            BMCWEB_LOG_ERROR << "Failed to get chassis subtree:" << ec.what();
            messages::internalError(asyncResp->res);
            return;
        }

        // Iterate over all retrieved ObjectPaths.
        for (const auto& [path, connectionNames] : subtree)
        {
            sdbusplus::message::object_path objPath(path);
            if (objPath.filename() != chassisId)
            {
                continue;
            }

            if (connectionNames.empty())
            {
                BMCWEB_LOG_DEBUG << "Got 0 Connection names";
                continue;
            }

            asyncResp->res.jsonValue["@odata.type"] =
                "#NetworkAdapterCollection.NetworkAdapterCollection";
            asyncResp->res.jsonValue["@odata.id"] =
                crow::utility::urlFromPieces("redfish", "v1", "Chassis",
                                             chassisId, "NetworkAdapters");
            asyncResp->res.jsonValue["Name"] = "NetworkAdapter Collection";

            // Get /network_adapter association
            dbus_utils::getAssociationEndPoints(
                path + "/network_adapter", requestContext,
                [asyncResp,
                 chassisId](const boost::system::error_code& ec1,
                            const dbus::utility::MapperEndPoints& resp) {
                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
                members = nlohmann::json::array();

                if (ec1)
                {
                    // "/network_adapter" association is optional for chassis
                    BMCWEB_LOG_DEBUG
                        << "Cannot get chassis NetworkAdapter association:"
                        << ec1.what();
                    asyncResp->res.jsonValue["Members@odata.count"] = 0;
                    return;
                }

                std::vector<std::string> leafNames;
                for (const auto& nic : resp)
                {
                    sdbusplus::message::object_path nicPath(nic);
                    leafNames.push_back(nicPath.filename());
                }

                std::sort(leafNames.begin(), leafNames.end(),
                          AlphanumLess<std::string>());

                for (const auto& leafName : leafNames)
                {
                    nlohmann::json::object_t member;
                    member["@odata.id"] = crow::utility::urlFromPieces(
                        "redfish", "v1", "Chassis", chassisId,
                        "NetworkAdapters", leafName);
                    members.push_back(std::move(member));
                }
                asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
            }); // end association lambda

            return; // No need to check other ObjectPaths

        } // end Iterate over all retrieved ObjectPaths

        // chassisId is not found
        messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
    });
}

// Chassis NetworkAdapters, this URL will show all the NetworkAdapterCollection
// information
inline void handleChassisNetworkAdapterCollectionGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId)
{
    handleChassisNetworkAdapterCommon(
        app, req, asyncResp, chassisId,
        handleChassisNetworkAdapterCollectionGetSysfs,
        handleChassisNetworkAdapterCollectionGetDBus);
}

inline void requestRoutesChassisNetworkAdapterCollection(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/NetworkAdapters/")
        .privileges(redfish::privileges::getNetworkAdapterCollection)
        .methods(boost::beast::http::verb::get)(std::bind_front(
            handleChassisNetworkAdapterCollectionGet, std::ref(app)));
}

inline void buildNetworkAdapterDBus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& service, const std::string& networkAdapterPath)
{

    asyncResp->res.jsonValue["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                     "NetworkAdapters", networkAdapterId);

    asyncResp->res.jsonValue["@odata.type"] =
        "#NetworkAdapter.v1_9_0.NetworkAdapter";
    asyncResp->res.jsonValue["Name"] = networkAdapterId;
    asyncResp->res.jsonValue["Id"] = networkAdapterId;
    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);

    dbus_utils::getProperty<std::string>(
        service, networkAdapterPath, networkAdapterInventoryIntf,
        "StatusHealth", requestContext,
        [asyncResp](const boost::system::error_code& ec,
                    const std::string& statusHealth) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Get StatusHealth property failed:"
                             << ec.what();
            messages::internalError(asyncResp->res);
            return;
        }

        if (statusHealth.empty())
        {
            BMCWEB_LOG_ERROR << "Empty StatusHealth property";
            messages::internalError(asyncResp->res);
            return;
        }

        asyncResp->res.jsonValue["Status"]["Health"] = statusHealth;
    });

    dbus_utils::getAssociationEndPoints(
        networkAdapterPath + "/all_ports", requestContext,
        [asyncResp, chassisId,
         networkAdapterId](const boost::system::error_code& ec,
                           const dbus::utility::MapperEndPoints& resp) {
        if (ec || resp.empty())
        {
            return; // no ports = no failures
        }
        nlohmann::json reference;
        reference["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
            networkAdapterId, "Ports");
        asyncResp->res.jsonValue["Ports"] = std::move(reference);
    });
}

inline void handleChassisNetworkAdapterGetSysfs(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId)
{

    // currently we only define one network adapter id and put all the bmc ports
    // under it.
    asyncResp->res.jsonValue["@odata.type"] = "#NetworkAdapter.NetworkAdapter";
    asyncResp->res.jsonValue["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                     "NetworkAdapters", networkAdapterId);
    asyncResp->res.jsonValue["Name"] = "Network adapter";
    asyncResp->res.jsonValue["Ports"]["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                     "NetworkAdapters", networkAdapterId,
                                     "Ports");
}

inline void handleChassisNetworkAdapterGetDBus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId)
{
    constexpr std::array<std::string_view, 1> interfaces = {
        networkAdapterInventoryIntf};
    // mapper call chassis
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        inventoryPrefix, 0, interfaces, requestContext,
        [asyncResp, chassisId, networkAdapterId, requestContext](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Get NetworkAdapter inventory failed:"
                             << ec.what();
            messages::internalError(asyncResp->res);
            return;
        }

        // Iterate over all retrieved ObjectPaths.
        for (const auto& [objectPath, serviceMap] : subtree)
        {
            std::string networkAdapterPath =
                crow::utility::urlFromPieces(
                    chassisId, networkAdapterId).buffer();
            if (!objectPath.ends_with(networkAdapterPath))
            {
                continue;
            }

            if (serviceMap.empty())
            {
                BMCWEB_LOG_DEBUG << "Got 0 Connection names";
                continue;
            }
            const std::string& serviceName = serviceMap[0].first;
            buildNetworkAdapterDBus(asyncResp, chassisId, networkAdapterId,
                                    serviceName, objectPath);
            return;
        }

        // chassisId is not found
        std::string networkAdapterPath =
            crow::utility::urlFromPieces(
                chassisId, networkAdapterId).buffer();
        messages::resourceNotFound(asyncResp->res, "Chassis/NetworkAdapter",
                                   networkAdapterId);
    });
}

inline void handleChassisNetworkAdapterGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId)
{
    handleChassisNetworkAdapterCommon(
        app, req, asyncResp, chassisId, handleChassisNetworkAdapterGetSysfs,
        handleChassisNetworkAdapterGetDBus, networkAdapterId);
}

inline void requestRoutesChassisNetworkAdapter(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/NetworkAdapters/<str>/")
        .privileges(redfish::privileges::getNetworkAdapter)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleChassisNetworkAdapterGet, std::ref(app)));
}

inline void handleNetworkPortCollectionGetSysfs(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId)
{
    /**
     * Functions triggers appropriate requests on DBus
     */

    // currently we only define one network adapter and put all the ports under
    // it.
    asyncResp->res.jsonValue["@odata.type"] = "#PortCollection.PortCollection";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
        networkAdapterId, "Ports");
    asyncResp->res.jsonValue["Name"] = "Network ports";
    nlohmann::json& members = asyncResp->res.jsonValue["Members"];
    members = nlohmann::json::array();
    for (auto& i : sysfsGetEtherDevList())
    {
        nlohmann::json::object_t member;
        member["@odata.id"] = crow::utility::urlFromPieces(
            "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
            networkAdapterId, "Ports", i);
        members.push_back(std::move(member));
    }
    asyncResp->res.jsonValue["Members@odata.count"] = members.size();
}

inline void buildNetworkPortCollectionDBus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& networkAdapterPath)
{
    asyncResp->res.jsonValue["@odata.type"] = "#PortCollection.PortCollection";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
        networkAdapterId, "Ports");
    asyncResp->res.jsonValue["Name"] = "Network Port Collection";

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getAssociationEndPoints(
        networkAdapterPath + "/all_ports", requestContext,
        [asyncResp, chassisId,
         networkAdapterId](const boost::system::error_code& ec,
                           const dbus::utility::MapperEndPoints& resp) {
        nlohmann::json& members = asyncResp->res.jsonValue["Members"];
        members = nlohmann::json::array();
        if (ec)
        {
            BMCWEB_LOG_DEBUG << "Cannot find chassis /all_ports association:"
                             << ec.what();
            asyncResp->res.jsonValue["Members@odata.count"] = 0;
            return;
        }

        std::vector<std::string> leafNames;
        for (const auto& port : resp)
        {
            sdbusplus::message::object_path portPath(port);
            leafNames.push_back(portPath.filename());
        }

        std::sort(leafNames.begin(), leafNames.end(),
                  AlphanumLess<std::string>());

        for (const auto& leafName : leafNames)
        {
            nlohmann::json::object_t member;
            member["@odata.id"] = crow::utility::urlFromPieces(
                "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
                networkAdapterId, "Ports", leafName);
            members.push_back(std::move(member));
        }
        asyncResp->res.jsonValue["Members@odata.count"] = members.size();
    }); // end association lambda
}

inline void handleNetworkPortCollectionGetDBus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId)
{
    constexpr std::array<std::string_view, 1> interfaces = {
        networkAdapterInventoryIntf};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        inventoryPrefix, 0, interfaces, requestContext,
        [asyncResp, chassisId, networkAdapterId, requestContext](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            if (ec == boost::system::errc::host_unreachable)
            {
                messages::resourceNotFound(
                    asyncResp->res, "#NetworkAdapter.v1_9_0.NetworkAdapter",
                    networkAdapterId);
                return;
            }
            BMCWEB_LOG_ERROR << "Failed to get " << networkAdapterInventoryIntf
                             << " due to :" << ec.what();
            messages::internalError(asyncResp->res);
            return;
        }

        // Iterate over all retrieved ObjectPaths.
        for (const auto& [path, connectionNames] : subtree)
        {
            std::string networkAdapterPath =
                crow::utility::urlFromPieces(
                    chassisId, networkAdapterId).buffer();
            if (!path.ends_with(networkAdapterPath))
            {
                continue;
            }

            if (connectionNames.empty())
            {
                BMCWEB_LOG_DEBUG << "Got 0 Connection names";
                continue;
            }

            buildNetworkPortCollectionDBus(asyncResp, chassisId,
                                           networkAdapterId, path);
            break;
        } // end Iterate over all retrieved ObjectPaths
    });
}

inline void handleNetworkPortCollectionGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId)
{
    handleChassisNetworkAdapterCommon(
        app, req, asyncResp, chassisId, handleNetworkPortCollectionGetSysfs,
        handleNetworkPortCollectionGetDBus, networkAdapterId);
}

inline void requestRoutesNetworkPortCollection(App& app)
{
    BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/NetworkAdapters/<str>/Ports/")
        .privileges(redfish::privileges::getPortCollection)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleNetworkPortCollectionGet, std::ref(app)));
}

inline void handleNetworkPortGetSysfs(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& portId)
{
    asyncResp->res.jsonValue["@odata.type"] = "#Port.Port";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
        networkAdapterId, "Ports", portId);
    asyncResp->res.jsonValue["Metrics"]["@odata.id"] =
        crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                     "NetworkAdapters", networkAdapterId,
                                     "Ports", portId, "Metrics");
    if (portId == "front")
    {
        asyncResp->res.jsonValue["Locations"]["ServiceLable"] =
            "FrontServiceLable";
    }

    std::vector<std::string> ethList = sysfsGetEthAddrList(portId);
    asyncResp->res.jsonValue["Ethernet"]["AssociatedMACAddresses"] =
        std::move(ethList);
    asyncResp->res.jsonValue["LinkState"] = sysfsGetLinkState(portId);
    if (asyncResp->res.jsonValue["LinkState"] == "Enabled")
    {
        asyncResp->res.jsonValue["LinkStatus"] = "LinkUp";
    }
    else
    {
        asyncResp->res.jsonValue["LinkStatus"] = "LinkDown";
    }
    asyncResp->res.jsonValue["CurrentSpeedGbps"] = sysfsGetSpeedGbps(portId);
    asyncResp->res.jsonValue["Name"] = portId;
}

inline void buildNetworkPortDBus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& portId, const std::string& serviceName,
    const std::string& networkPortPath)
{
    asyncResp->res.jsonValue["@odata.type"] = "#Port.v1_9_0.Port";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
        networkAdapterId, "Ports", portId);
    asyncResp->res.jsonValue["Name"] = portId;
    asyncResp->res.jsonValue["Id"] = portId;

    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getAllProperties(
        serviceName, networkPortPath, portInventoryIntf, requestContext,
        [asyncResp, serviceName, networkPortPath](
            const boost::system::error_code& ec,
            const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "getAllProperties on path " << networkPortPath
                             << " iface " << portInventoryIntf << " service "
                             << serviceName << " failed with code "
                             << ec.what();
            messages::internalError(asyncResp->res);
            return;
        }

        const std::string* linkState = nullptr;
        const std::string* linkStatus = nullptr;
        const double* currentSpeedGbps = nullptr;

        const bool success = sdbusplus::unpackPropertiesNoThrow(
            dbus_utils::UnpackErrorPrinter(), propertiesList, "LinkState",
            linkState, "LinkStatus", linkStatus, "CurrentSpeedGbps",
            currentSpeedGbps);

        if (!success)
        {
            BMCWEB_LOG_ERROR << "Failed to unpack " << portInventoryIntf;
            messages::internalError(asyncResp->res);
            return;
        }

        if (linkState == nullptr || linkState->empty())
        {
            BMCWEB_LOG_ERROR << "Empty LinkState property in "
                             << portInventoryIntf;
            messages::internalError(asyncResp->res);
            return;
        }
        asyncResp->res.jsonValue["LinkState"] = *linkState;

        if (linkStatus == nullptr || linkStatus->empty())
        {
            BMCWEB_LOG_ERROR << "Empty LinkStatus property in "
                             << portInventoryIntf;
            messages::internalError(asyncResp->res);
            return;
        }
        asyncResp->res.jsonValue["LinkStatus"] = *linkStatus;

        if (currentSpeedGbps == nullptr)
        {
            BMCWEB_LOG_ERROR << "Empty CurrentSpeedGbps property in "
                             << portInventoryIntf;
            messages::internalError(asyncResp->res);
            return;
        }
        asyncResp->res.jsonValue["CurrentSpeedGbps"] = *currentSpeedGbps;
    });
}

inline void handleNetworkPortGetDBus(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& portId)
{
    constexpr std::array<std::string_view, 1> interfaces = {portInventoryIntf};
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTree(
        inventoryPrefix, 0, interfaces, requestContext,
        [asyncResp, chassisId, networkAdapterId, portId, requestContext](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec)
        {
            if (ec == boost::system::errc::host_unreachable)
            {
                messages::resourceNotFound(asyncResp->res, "#Port.v1_9_0.Port",
                                           portId);
                return;
            }
            BMCWEB_LOG_ERROR << "Failed to get " << portInventoryIntf
                             << " due to:" << ec.what();
            messages::internalError(asyncResp->res);
            return;
        }

        // Iterate over all retrieved ObjectPaths.
        for (const auto& [path, connectionNames] : subtree)
        {
            std::string portIdPath =
                crow::utility::urlFromPieces(
                    chassisId, networkAdapterId, portId).buffer();
            if (!path.ends_with(portIdPath))
            {
                continue;
            }

            if (connectionNames.empty())
            {
                BMCWEB_LOG_DEBUG << "Got 0 Connection names";
                continue;
            }

            const std::string& serviceName = connectionNames[0].first;
            buildNetworkPortDBus(asyncResp, chassisId, networkAdapterId, portId,
                                 serviceName, path);
            return;
        } // end Iterate over all retrieved ObjectPaths

        messages::resourceNotFound(asyncResp->res, "#Port.v1_9_0.Port", portId);
    });
}

inline void
    handleNetworkPortGet(crow::App& app, const crow::Request& req,
                         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                         const std::string& chassisId,
                         const std::string& networkAdapterId,
                         const std::string& portId)
{
    handleChassisNetworkAdapterCommon(
        app, req, asyncResp, chassisId, handleNetworkPortGetSysfs,
        handleNetworkPortGetDBus, networkAdapterId, portId);
}

inline void requestRoutesNetworkPort(App& app)
{
    BMCWEB_ROUTE(app,
                 "/redfish/v1/Chassis/<str>/NetworkAdapters/<str>/Ports/<str>/")
        .privileges(redfish::privileges::getPort)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleNetworkPortGet, std::ref(app)));
}

inline void handleNetworkPortMetricGetSysfs(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& portId)
{
    asyncResp->res.jsonValue["@odata.type"] = "#PortMetrics.PortMetrics";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
        networkAdapterId, "Ports", portId, "Metrics");
    asyncResp->res.jsonValue["Name"] = "Network port metrics";
    asyncResp->res.jsonValue["Oem"]["Google"]["Networking"] =
        sysfsGetNetworkPortMetrics(portId);
}

inline void handleNetworkPortMetricGetDBus(
    [[maybe_unused]] const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& portId)
{
    BMCWEB_LOG_ERROR << "Metric not supported: chassis " << chassisId
                     << " network adapter " << networkAdapterId << " port "
                     << portId;
}

inline void handleNetworkPortMetricGet(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& chassisId, const std::string& networkAdapterId,
    const std::string& portId)
{
    handleChassisNetworkAdapterCommon(
        app, req, asyncResp, chassisId, handleNetworkPortMetricGetSysfs,
        handleNetworkPortMetricGetDBus, networkAdapterId, portId);
}

inline void requestRoutesNetworkPortMetrics(App& app)
{
    BMCWEB_ROUTE(
        app,
        "/redfish/v1/Chassis/<str>/NetworkAdapters/<str>/Ports/<str>/Metrics")
        .privileges(redfish::privileges::getPortMetrics)
        .methods(boost::beast::http::verb::get)(
            std::bind_front(handleNetworkPortMetricGet, std::ref(app)));
}

} // namespace redfish
