#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NETWORK_ADAPTER_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NETWORK_ADAPTER_H_

/*
// 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.
*/

#include <algorithm>
#include <array>
#include <charconv>
#include <cstdint>
#include <filesystem>  // NOLINT
#include <fstream>
#include <functional>
#include <limits>
#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>

#include "absl/strings/str_cat.h"
#include "boost/system/error_code.hpp"  // NOLINT
#include "bmcweb_config.h"
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "human_sort.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "dbus_utils.hpp"
#include "location_utils.hpp"
#include <nlohmann/json.hpp>
#include "bmcweb_authorizer_singleton.h"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"
#include "sdbusplus/unpack_properties.hpp"

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 G3_UNIT_TEST_BUILD
constexpr const char* netSysfsPath =
    "third_party/openbmc_build_scripts/additional/sys/class/net";
#else
#ifdef UNIT_TEST_BUILD
constexpr const char* netSysfsPath = sysfsNetBasePathUT;
#else
constexpr const char* netSysfsPath = "/sys/class/net/";
#endif

#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.data(), str.data() + str.size(), value);
  return value;
}

// Helper function for convert a hex string to uint64 type
// if string is invalid, return default val instead
static uint64_t hexStringToUint64(const std::string_view str,
                                  uint64_t defVal = 0) {
  uint64_t value = defVal;
  // Handle the "0x" or "0X" prefix for hex string
  if (str.size() >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
    std::from_chars(str.data() + 2, str.data() + str.size(), value, 16);
  }
  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>(hexStringToUint64(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 static_cast<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 " + chassisId;
  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["Id"] = portId;
  asyncResp->res.jsonValue["Metrics"]["@odata.id"] =
      crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                   "NetworkAdapters", networkAdapterId, "Ports",
                                   portId, "Metrics");
  if (std::string(bmcDirectPathIntf).find(portId) != std::string::npos &&
      ::milotic::authz::BmcWebAuthorizerSingleton::GetInstance()
          .HasBmcDirectEthernet()) {
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    dbus_utils::getProperty<std::string>(
        "xyz.openbmc_project.EntityManager",
        "/xyz/openbmc_project/inventory/system/board/" + chassisId + "/BmcNet",
        "xyz.openbmc_project.Configuration.BmcNet", "LocationCode",
        requestContext,
        [asyncResp, chassisId](const boost::system::error_code& ec,
                               const std::string& locationCode) {
          if (ec) {
            BMCWEB_LOG_ERROR << "Fail to get LocationCode for front cable: "
                             << ec.what();
            return;
          }
          // Get Chassis location code
          managedStore::ManagedObjectStoreContext requestContext2(asyncResp);
          dbus_utils::getProperty<std::string>(
              "xyz.openbmc_project.EntityManager",
              "/xyz/openbmc_project/inventory/system/board/" + chassisId,
              "xyz.openbmc_project.Inventory.Decorator.LocationCode",
              "LocationCode", requestContext2,
              [asyncResp, locationCode, chassisId](
                  const boost::system::error_code& ec2,
                  const std::string& chassisLocationCode) {
                if (ec2) {
                  BMCWEB_LOG_ERROR << "Fail to get LocationCode for chassis: "
                                   << ec2.what();
                  return;
                }
                asyncResp->res
                    .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
                    locationCode;
                asyncResp->res
                    .jsonValue["Location"]["PartLocation"]["LocationType"] =
                    "Slot";
                asyncResp->res.jsonValue["Location"]["PartLocationContext"] =
                    chassisLocationCode;

                asyncResp->res.jsonValue["Oem"]["Google"]["ConnectionPath"] =
                    "DIRECT";
                asyncResp->res
                    .jsonValue["Location"]["Oem"]["Google"]["Devpath"] =
                    "/phys/" + chassisLocationCode + "/" + locationCode;
                // recursively find the full oem devpath and PartLocationContext
                redfish::location_util::getLocationContextWithOemDevpath(
                    asyncResp, "/Location"_json_pointer,
                    "/xyz/openbmc_project/inventory/system/board/" + chassisId +
                        "/contained_by");
              });
        });
  } else if (std::string(bmcSidePathIntf).find(portId) != std::string::npos) {
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Configuration.Port"};
    managedStore::ManagedObjectStoreContext requestContext3(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/xyz/openbmc_project/inventory/system/cable/", 0, interfaces,
        requestContext3,
        [asyncResp, portId](
            const boost::system::error_code& ec3,
            const dbus::utility::MapperGetSubTreePathsResponse& cableList) {
          if (ec3) {
            BMCWEB_LOG_ERROR << "Fail to get subtree for cables: "
                             << ec3.what();
            return;
          }
          for (const auto& pathStr : cableList) {
            if (pathStr.size() - portId.size() > 0 &&
                pathStr.substr(pathStr.size() - portId.size()) == portId) {
              // get the cable location code
              managedStore::ManagedObjectStoreContext requestContext4(
                  asyncResp);
              dbus_utils::getProperty<std::string>(
                  "xyz.openbmc_project.EntityManager",
                  pathStr.substr(0, pathStr.size() - portId.size() - 1),
                  "xyz.openbmc_project.Inventory.Decorator.LocationCode",
                  "LocationCode", requestContext4,
                  [asyncResp](const boost::system::error_code& ec4,
                              const std::string& cableLocationCode) {
                    if (ec4) {
                      BMCWEB_LOG_ERROR << "Fail to get LocationCode for cable: "
                                       << ec4.what();
                      return;
                    }
                    asyncResp->res
                        .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
                        cableLocationCode;
                    asyncResp->res
                        .jsonValue["Location"]["Oem"]["Google"]["Devpath"] =
                        "/phys/" + cableLocationCode;
                    asyncResp->res
                        .jsonValue["Oem"]["Google"]["ConnectionPath"] = "SIDE";
                  });
              break;
            }
          }
        });
  } else {
    // usb sideband using ifalias
    std::string ifalias;
    if (readOneLineFile(
            std::filesystem::path(netSysfsPath) / portId / "ifalias",
            ifalias)) {
      if (ifalias.size() >= 5 &&
          ifalias.compare(ifalias.size() - 5, 5, "-side") == 0) {
        managedStore::ManagedObjectStoreContext requestContext5(asyncResp);
        managedStore::GetManagedObjectStore()->getAllProperties(
            "xyz.openbmc_project.EntityManager",
            "/xyz/openbmc_project/inventory/system/board/" + chassisId + "/" +
                portId,
            "xyz.openbmc_project.Configuration.BmcNet_Side", requestContext5,
            [asyncResp](
                const boost::system::error_code& ec5,
                const dbus::utility::DBusPropertiesMap& propertiesList) {
              if (ec5) {
                BMCWEB_LOG_ERROR << "GetAllProperties failed: " << ec5.what();
                return;
              }
              const std::string* locationCode = nullptr;
              const std::string* partLocationContext = nullptr;
              const bool success = sdbusplus::unpackPropertiesNoThrow(
                  dbus_utils::UnpackErrorPrinter(), propertiesList,
                  "LocationCode", locationCode, "PartLocationContext",
                  partLocationContext);
              if (!success) {
                BMCWEB_LOG_ERROR << "Failed to unpack BmcNet_Side properties";
                return;
              }
              if (locationCode != nullptr) {
                asyncResp->res
                    .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
                    *locationCode;
              }
              if (partLocationContext != nullptr) {
                asyncResp->res.jsonValue["Location"]["PartLocationContext"] =
                    *partLocationContext;
              }
              asyncResp->res.jsonValue["Oem"]["Google"]["ConnectionPath"] =
                  "SIDEBAND";
            });
      }
    }
  }

  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;
  asyncResp->res.jsonValue["Metrics"]["@odata.id"] =
      crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId,
                                   "NetworkAdapters", networkAdapterId, "Ports",
                                   portId, "Metrics");

  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 buildNetworkPortMetricDBus(
    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"] = "#PortMetrics.v1_3_0.PortMetrics";
  asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Chassis", chassisId, "NetworkAdapters",
      networkAdapterId, "Ports", portId, "Metrics");
  asyncResp->res.jsonValue["Name"] = portId + " Metrics";
  asyncResp->res.jsonValue["Id"] = "Metrics";
  asyncResp->res.jsonValue["CorrectableBitErrors"] = 0;
  asyncResp->res.jsonValue["SymbolErrors"] = 0;
  asyncResp->res.jsonValue["RXBroadcastPackets"] = 0;
  asyncResp->res.jsonValue["RXMulticastPackets"] = 0;
  asyncResp->res.jsonValue["RXUnicastPackets"] = 0;
  asyncResp->res.jsonValue["TXBroadcastPackets"] = 0;
  asyncResp->res.jsonValue["TXMulticastPackets"] = 0;
  asyncResp->res.jsonValue["TXUnicastPackets"] = 0;
  asyncResp->res
      .jsonValue["Oem"]["Google"]["TransceiverTelemetry"]["FECCorrectedCount"] =
      0;
  asyncResp->res.jsonValue["Oem"]["Google"]["TransceiverTelemetry"]
                          ["FECUncorrectableCount"] = 0;
  asyncResp->res.jsonValue["Oem"]["Google"]["TransceiverTelemetry"]
                          ["PerLaneFECCounters"] = nlohmann::json::array();
  asyncResp->res
      .jsonValue["Oem"]["Google"]["TransceiverTelemetry"]["FECHistogramBins"] =
      nlohmann::json::array();

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);

  // Query PortECC metrics
  managedStore::GetManagedObjectStore()->getAllProperties(
      serviceName, networkPortPath, "xyz.openbmc_project.Metrics.PortECC",
      requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec) {
          return;
        }
        for (const auto& [propName, propValue] : propertiesList) {
          uint64_t numVal = 0;
          bool hasNum = false;
          std::visit(
              [&numVal, &hasNum](const auto& v) {
                using T = std::decay_t<decltype(v)>;
                if constexpr (std::is_arithmetic_v<T>) {
                  numVal = static_cast<uint64_t>(v);
                  hasNum = true;
                }
              },
              propValue);

          if (hasNum) {
            if (propName == "CorrectedBits") {
              asyncResp->res.jsonValue["CorrectableBitErrors"] = numVal;
              asyncResp->res.jsonValue["Oem"]["Google"]["TransceiverTelemetry"]
                                      ["FECCorrectedCount"] = numVal;
            } else if (propName == "SymbolErrorRXBytes") {
              asyncResp->res.jsonValue["SymbolErrors"] = numVal;
              asyncResp->res.jsonValue["Oem"]["Google"]["TransceiverTelemetry"]
                                      ["FECUncorrectableCount"] = numVal;
            }
          }
          if (propName == "RawErrorsPerLane") {
            std::visit(
                [asyncResp](const auto& v) {
                  using T = std::decay_t<decltype(v)>;
                  if constexpr (std::is_same_v<T, std::vector<uint32_t>> ||
                                std::is_same_v<T, std::vector<uint64_t>> ||
                                std::is_same_v<T, std::vector<int32_t>> ||
                                std::is_same_v<T, std::vector<int64_t>>) {
                    std::vector<uint64_t> uCounters;
                    uCounters.reserve(v.size());
                    for (auto elem : v) {
                      uCounters.push_back(static_cast<uint64_t>(elem));
                    }
                    asyncResp->res
                        .jsonValue["Oem"]["Google"]["TransceiverTelemetry"]
                                  ["PerLaneFECCounters"] = uCounters;
                  }
                },
                propValue);
          }
        }
      });

  // Query PortPacketCounters
  managedStore::GetManagedObjectStore()->getAllProperties(
      serviceName, networkPortPath,
      "xyz.openbmc_project.Metrics.PortPacketCounters", requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec) {
          return;
        }
        for (const auto& [propName, propValue] : propertiesList) {
          uint64_t numVal = 0;
          bool hasNum = false;
          std::visit(
              [&numVal, &hasNum](const auto& v) {
                using T = std::decay_t<decltype(v)>;
                if constexpr (std::is_arithmetic_v<T>) {
                  numVal = static_cast<uint64_t>(v);
                  hasNum = true;
                }
              },
              propValue);

          if (hasNum) {
            if (propName == "RXBroadcastPkts") {
              asyncResp->res.jsonValue["RXBroadcastPackets"] = numVal;
            } else if (propName == "RXMulticastPkts") {
              asyncResp->res.jsonValue["RXMulticastPackets"] = numVal;
            } else if (propName == "RXUnicastPkts") {
              asyncResp->res.jsonValue["RXUnicastPackets"] = numVal;
            } else if (propName == "TXBroadcastPkts") {
              asyncResp->res.jsonValue["TXBroadcastPackets"] = numVal;
            } else if (propName == "TXMulticastPkts") {
              asyncResp->res.jsonValue["TXMulticastPackets"] = numVal;
            } else if (propName == "TXUnicastPkts") {
              asyncResp->res.jsonValue["TXUnicastPackets"] = numVal;
            }
          }
        }
      });

  // Query EthPort metrics
  managedStore::GetManagedObjectStore()->getAllProperties(
      serviceName, networkPortPath, "xyz.openbmc_project.Metrics.EthPort",
      requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec) {
          return;
        }
        for (const auto& [propName, propValue] : propertiesList) {
          uint64_t numVal = 0;
          bool hasNum = false;
          std::visit(
              [&numVal, &hasNum](const auto& v) {
                using T = std::decay_t<decltype(v)>;
                if constexpr (std::is_arithmetic_v<T>) {
                  numVal = static_cast<uint64_t>(v);
                  hasNum = true;
                }
              },
              propValue);

          if (hasNum) {
            if (propName == "RXFCSErrors") {
              asyncResp->res.jsonValue["RXFCSErrors"] = numVal;
            } else if (propName == "RXAlignmentErrors") {
              asyncResp->res.jsonValue["RXAlignmentErrors"] = numVal;
            } else if (propName == "RXFalseCarrierDetections") {
              asyncResp->res.jsonValue["RXFalseCarrierDetections"] = numVal;
            } else if (propName == "RXRuntPkts") {
              asyncResp->res.jsonValue["RXRuntPackets"] = numVal;
            } else if (propName == "RXJabberPkts") {
              asyncResp->res.jsonValue["RXJabberPackets"] = numVal;
            } else if (propName == "RXXOFFFrames") {
              asyncResp->res.jsonValue["PauseXOFFFramesReceived"] = numVal;
            } else if (propName == "RXXONFrames") {
              asyncResp->res.jsonValue["PauseXONFramesReceived"] = numVal;
            } else if (propName == "TXXOFFFrames") {
              asyncResp->res.jsonValue["PauseXOFFFramesTransmitted"] = numVal;
            } else if (propName == "TXXONFrames") {
              asyncResp->res.jsonValue["PauseXONFramesTransmitted"] = numVal;
            } else if (propName == "TXSingleCollisionFrames") {
              asyncResp->res.jsonValue["SingleCollisionTransmitFrames"] =
                  numVal;
            } else if (propName == "TXMultipleCollisionFrames") {
              asyncResp->res.jsonValue["MultipleCollisionTransmitFrames"] =
                  numVal;
            } else if (propName == "TXLateCollisionFrames") {
              asyncResp->res.jsonValue["LateCollisionFrames"] = numVal;
            } else if (propName == "TXExcessCollisionFrames") {
              asyncResp->res.jsonValue["ExcessiveCollisionFrames"] = numVal;
            }
          }
        }
      });

  // Query IBPort metrics
  managedStore::GetManagedObjectStore()->getAllProperties(
      serviceName, networkPortPath, "xyz.openbmc_project.Metrics.IBPort",
      requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec) {
          return;
        }
        for (const auto& [propName, propValue] : propertiesList) {
          if (propName == "BitErrorRate" || propName == "EffectiveBER" ||
              propName == "TotalRawBER") {
            double dVal = 0.0;
            bool hasD = false;
            std::visit(
                [&dVal, &hasD](const auto& v) {
                  using T = std::decay_t<decltype(v)>;
                  if constexpr (std::is_floating_point_v<T> ||
                                std::is_arithmetic_v<T>) {
                    dVal = static_cast<double>(v);
                    hasD = true;
                  }
                },
                propValue);
            if (hasD) {
              asyncResp->res.jsonValue["Oem"]["Google"]["TransceiverTelemetry"]
                                      [propName] = dVal;
            }
          } else if (propName == "LinkDownCount") {
            uint64_t numVal = 0;
            bool hasNum = false;
            std::visit(
                [&numVal, &hasNum](const auto& v) {
                  using T = std::decay_t<decltype(v)>;
                  if constexpr (std::is_arithmetic_v<T>) {
                    numVal = static_cast<uint64_t>(v);
                    hasNum = true;
                  }
                },
                propValue);
            if (hasNum) {
              asyncResp->res.jsonValue["LinkDownCount"] = numVal;
            }
          }
        }
      });

  // Query PortMetricsOem2 (RXBytes, TXBytes)
  managedStore::GetManagedObjectStore()->getAllProperties(
      serviceName, networkPortPath,
      "xyz.openbmc_project.Metrics.PortMetricsOem2", requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec) {
          return;
        }
        for (const auto& [propName, propValue] : propertiesList) {
          uint64_t numVal = 0;
          bool hasNum = false;
          std::visit(
              [&numVal, &hasNum](const auto& v) {
                using T = std::decay_t<decltype(v)>;
                if constexpr (std::is_arithmetic_v<T>) {
                  numVal = static_cast<uint64_t>(v);
                  hasNum = true;
                }
              },
              propValue);

          if (hasNum) {
            if (propName == "RXBytes") {
              asyncResp->res.jsonValue["RXBytes"] = numVal;
            } else if (propName == "TXBytes") {
              asyncResp->res.jsonValue["TXBytes"] = numVal;
            }
          }
        }
      });

  // Query PCIeECC
  managedStore::GetManagedObjectStore()->getAllProperties(
      serviceName, networkPortPath, "xyz.openbmc_project.PCIe.PCIeECC",
      requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const dbus::utility::DBusPropertiesMap& propertiesList) {
        if (ec) {
          return;
        }
        nlohmann::json& pcieObj =
            asyncResp->res.jsonValue["Oem"]["Google"]["PCIeErrors"];
        for (const auto& [propName, propValue] : propertiesList) {
          uint64_t val = 0;
          bool hasVal = false;
          std::visit(
              [&val, &hasVal](const auto& v) {
                using T = std::decay_t<decltype(v)>;
                if constexpr (std::is_arithmetic_v<T>) {
                  val = static_cast<uint64_t>(v);
                  hasVal = true;
                }
              },
              propValue);
          if (hasVal) {
            pcieObj[propName] = val;
          }
        }
      });
}

inline void handleNetworkPortMetricGetDBus(
    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, "#PortMetrics.v1_3_0.PortMetrics", portId);
            return;
          }
          BMCWEB_LOG_ERROR << "Failed to get " << portInventoryIntf
                           << " due to:" << ec.what();
          messages::internalError(asyncResp->res);
          return;
        }

        std::string matchingPath;
        std::string matchingService;
        std::string portIdSuffix1 =
            absl::StrCat("/", chassisId, "/", networkAdapterId, "/", portId);
        std::string portIdSuffix2 =
            absl::StrCat("/", chassisId, "/NetworkAdapters/", networkAdapterId,
                         "/Ports/", portId);

        for (const auto& [path, connectionNames] : subtree) {
          if (path.ends_with(portIdSuffix1) || path.ends_with(portIdSuffix2)) {
            if (!connectionNames.empty()) {
              matchingPath = path;
              matchingService = connectionNames[0].first;
              break;
            }
          }
        }

        if (!matchingPath.empty()) {
          buildNetworkPortMetricDBus(asyncResp, chassisId, networkAdapterId,
                                     portId, matchingService, matchingPath);
          return;
        }

        messages::resourceNotFound(asyncResp->res,
                                   "#PortMetrics.v1_3_0.PortMetrics", 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

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NETWORK_ADAPTER_H_
