/*
// 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";
    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",
        networkAdapterId, "Ports");
    members.push_back(std::move(member));
    asyncResp->res.jsonValue["Members@odata.count"] = members.size();
}

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
