#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_HYPERVISOR_SYSTEM_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_HYPERVISOR_SYSTEM_H_

#include <array>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <variant>
#include <vector>

#include "boost/container/flat_set.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "dbus_utils.hpp"
#include "ip_utils.hpp"
#include "json_utils.hpp"
#include "ethernet.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"

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

namespace redfish {

/**
 * @brief Retrieves hypervisor state properties over dbus
 *
 * The hypervisor state object is optional so this function will only set the
 * state variables if the object is found
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 *
 * @return None.
 */
inline void getHypervisorState(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get hypervisor state information.";
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.State.Hypervisor",
      "/xyz/openbmc_project/state/hypervisor0",
      "xyz.openbmc_project.State.Host", "CurrentHostState", requestContext,
      [aResp](const boost::system::error_code& ec,
              const std::string& hostState) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          // This is an optional D-Bus object so just return if
          // error occurs
          return;
        }

        BMCWEB_LOG_DEBUG << "Hypervisor state: " << hostState;
        // Verify Host State
        if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") {
          aResp->res.jsonValue["PowerState"] = "On";
          aResp->res.jsonValue["Status"]["State"] = "Enabled";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState."
                   "Quiesced") {
          aResp->res.jsonValue["PowerState"] = "On";
          aResp->res.jsonValue["Status"]["State"] = "Quiesced";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState."
                   "Standby") {
          aResp->res.jsonValue["PowerState"] = "On";
          aResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState."
                   "TransitioningToRunning") {
          aResp->res.jsonValue["PowerState"] = "PoweringOn";
          aResp->res.jsonValue["Status"]["State"] = "Starting";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState."
                   "TransitioningToOff") {
          aResp->res.jsonValue["PowerState"] = "PoweringOff";
          aResp->res.jsonValue["Status"]["State"] = "Enabled";
        } else if (hostState ==
                   "xyz.openbmc_project.State.Host.HostState.Off") {
          aResp->res.jsonValue["PowerState"] = "Off";
          aResp->res.jsonValue["Status"]["State"] = "Disabled";
        } else {
          messages::internalError(aResp->res);
          return;
        }
      });
}

/**
 * @brief Populate Actions if any are valid for hypervisor object
 *
 * The hypervisor state object is optional so this function will only set the
 * Action if the object is found
 *
 * @param[in] aResp     Shared pointer for completing asynchronous calls.
 *
 * @return None.
 */
inline void getHypervisorActions(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp) {
  BMCWEB_LOG_DEBUG << "Get hypervisor actions.";
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.State.Host"};
  managedStore::ManagedObjectStoreContext requestContext(aResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      "/xyz/openbmc_project/state/hypervisor0", interfaces, requestContext,
      [aResp](
          const boost::system::error_code& ec,
          const std::vector<std::pair<std::string, std::vector<std::string>>>&
              objInfo) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
          // This is an optional D-Bus object so just return if
          // error occurs
          return;
        }

        if (objInfo.empty()) {
          // As noted above, this is an optional interface so just return
          // if there is no instance found
          return;
        }

        if (objInfo.size() > 1) {
          // More then one hypervisor object is not supported and is an
          // error
          messages::internalError(aResp->res);
          return;
        }

        // Object present so system support limited ComputerSystem Action
        nlohmann::json& reset =
            aResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"];
        reset["target"] =
            "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset";
        reset["@Redfish.ActionInfo"] =
            "/redfish/v1/Systems/hypervisor/ResetActionInfo";
      });
}

inline bool extractHypervisorInterfaceData(
    const std::string& ethIfaceId,
    const dbus::utility::ManagedObjectType& dbusData,
    EthernetInterfaceData& ethData,
    boost::container::flat_set<IPv4AddressData>& ipv4Config) {
  bool idFound = false;
  for (const auto& objpath : dbusData) {
    for (const auto& ifacePair : objpath.second) {
      if (objpath.first ==
          "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId) {
        idFound = true;
        if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress") {
          for (const auto& propertyPair : ifacePair.second) {
            if (propertyPair.first == "MACAddress") {
              const std::string* mac =
                  std::get_if<std::string>(&propertyPair.second);
              if (mac != nullptr) {
                ethData.macAddress = *mac;
              }
            }
          }
        } else if (ifacePair.first ==
                   "xyz.openbmc_project.Network.EthernetInterface") {
          for (const auto& propertyPair : ifacePair.second) {
            if (propertyPair.first == "DHCPEnabled") {
              const std::string* dhcp =
                  std::get_if<std::string>(&propertyPair.second);
              if (dhcp != nullptr) {
                ethData.dhcpEnabled = *dhcp;
                break;  // Interested on only "DHCPEnabled".
                        // Stop parsing since we got the
                        // "DHCPEnabled" value.
              }
            }
          }
        }
      }
      if (objpath.first == "/xyz/openbmc_project/network/hypervisor/" +
                               ethIfaceId + "/ipv4/addr0") {
        std::pair<boost::container::flat_set<IPv4AddressData>::iterator, bool>
            it = ipv4Config.insert(IPv4AddressData{});
        IPv4AddressData& ipv4Address = *it.first;
        if (ifacePair.first == "xyz.openbmc_project.Object.Enable") {
          for (const auto& property : ifacePair.second) {
            if (property.first == "Enabled") {
              const bool* intfEnable = std::get_if<bool>(&property.second);
              if (intfEnable != nullptr) {
                ipv4Address.isActive = *intfEnable;
                break;
              }
            }
          }
        }
        if (ifacePair.first == "xyz.openbmc_project.Network.IP") {
          for (const auto& property : ifacePair.second) {
            if (property.first == "Address") {
              const std::string* address =
                  std::get_if<std::string>(&property.second);
              if (address != nullptr) {
                ipv4Address.address = *address;
              }
            } else if (property.first == "Origin") {
              const std::string* origin =
                  std::get_if<std::string>(&property.second);
              if (origin != nullptr) {
                ipv4Address.origin =
                    translateAddressOriginDbusToRedfish(*origin, true);
              }
            } else if (property.first == "PrefixLength") {
              const uint8_t* mask = std::get_if<uint8_t>(&property.second);
              if (mask != nullptr) {
                // convert it to the string
                ipv4Address.netmask = getNetmask(*mask);
              }
            } else if (property.first == "Type" ||
                       property.first == "Gateway") {
              // Type & Gateway is not used
              continue;
            } else {
              BMCWEB_LOG_ERROR << "Got extra property: " << property.first
                               << " on the " << objpath.first.str << " object";
            }
          }
        }
      }
      if (objpath.first == "/xyz/openbmc_project/network/hypervisor") {
        // System configuration shows up in the global namespace, so no
        // need to check eth number
        if (ifacePair.first ==
            "xyz.openbmc_project.Network.SystemConfiguration") {
          for (const auto& propertyPair : ifacePair.second) {
            if (propertyPair.first == "HostName") {
              const std::string* hostName =
                  std::get_if<std::string>(&propertyPair.second);
              if (hostName != nullptr) {
                ethData.hostName = *hostName;
              }
            } else if (propertyPair.first == "DefaultGateway") {
              const std::string* defaultGateway =
                  std::get_if<std::string>(&propertyPair.second);
              if (defaultGateway != nullptr) {
                ethData.defaultGateway = *defaultGateway;
              }
            }
          }
        }
      }
    }
  }
  return idFound;
}
/**
 * Function that retrieves all properties for given Hypervisor Ethernet
 * Interface Object from Settings Manager
 * @param ethIfaceId Hypervisor ethernet interface id to query on DBus
 * @param callback a function that shall be called to convert Dbus output
 * into JSON
 */
template <typename CallbackFunc>
void getHypervisorIfaceData(
    const std::string& ethIfaceId,
    const managedStore::ManagedObjectStoreContext& context,
    CallbackFunc&& callback) {
  managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
      "xyz.openbmc_project.Settings", {"/"}, context,
      [ethIfaceId{std::string{ethIfaceId}},
       callback{std::forward<CallbackFunc>(callback)}](
          const boost::system::error_code& error,
          const dbus::utility::ManagedObjectType& resp) {
        EthernetInterfaceData ethData{};
        boost::container::flat_set<IPv4AddressData> ipv4Data;
        if (error) {
          callback(false, ethData, ipv4Data);
          return;
        }

        bool found =
            extractHypervisorInterfaceData(ethIfaceId, resp, ethData, ipv4Data);
        if (!found) {
          BMCWEB_LOG_INFO << "Hypervisor Interface not found";
        }
        callback(found, ethData, ipv4Data);
      });
}

/**
 * @brief Sets the Hypervisor Interface IPAddress DBUS
 *
 * @param[in] aResp          Shared pointer for generating response message.
 * @param[in] ipv4Address    Address from the incoming request
 * @param[in] ethIfaceId     Hypervisor Interface Id
 *
 * @return None.
 */
inline void setHypervisorIPv4Address(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& ethIfaceId, const std::string& ipv4Address) {
  BMCWEB_LOG_DEBUG << "Setting the Hypervisor IPaddress : " << ipv4Address
                   << " on Iface: " << ethIfaceId;
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      [aResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error " << ec;
          return;
        }
        BMCWEB_LOG_DEBUG << "Hypervisor IPaddress is Set";
      },
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId + "/ipv4/addr0",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Network.IP", "Address",
      dbus::utility::DbusVariantType(ipv4Address));
}

/**
 * @brief Sets the Hypervisor Interface SubnetMask DBUS
 *
 * @param[in] aResp     Shared pointer for generating response message.
 * @param[in] subnet    SubnetMask from the incoming request
 * @param[in] ethIfaceId Hypervisor Interface Id
 *
 * @return None.
 */
inline void setHypervisorIPv4Subnet(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& ethIfaceId, const uint8_t subnet) {
  BMCWEB_LOG_DEBUG << "Setting the Hypervisor subnet : " << subnet
                   << " on Iface: " << ethIfaceId;

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      [aResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error " << ec;
          return;
        }
        BMCWEB_LOG_DEBUG << "SubnetMask is Set";
      },
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId + "/ipv4/addr0",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Network.IP", "PrefixLength",
      dbus::utility::DbusVariantType(subnet));
}

/**
 * @brief Sets the Hypervisor Interface Gateway DBUS
 *
 * @param[in] aResp          Shared pointer for generating response message.
 * @param[in] gateway        Gateway from the incoming request
 * @param[in] ethIfaceId     Hypervisor Interface Id
 *
 * @return None.
 */
inline void setHypervisorIPv4Gateway(
    const std::shared_ptr<bmcweb::AsyncResp>& aResp,
    const std::string& gateway) {
  BMCWEB_LOG_DEBUG
      << "Setting the DefaultGateway to the last configured gateway";

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      aResp->strand_,
      [aResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error " << ec;
          return;
        }
        BMCWEB_LOG_DEBUG << "Default Gateway is Set";
      },
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/hypervisor",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Network.SystemConfiguration", "DefaultGateway",
      dbus::utility::DbusVariantType(gateway));
}

/**
 * @brief Creates a static IPv4 entry
 *
 * @param[in] ifaceId      Id of interface upon which to create the IPv4 entry
 * @param[in] prefixLength IPv4 prefix syntax for the subnet mask
 * @param[in] gateway      IPv4 address of this interfaces gateway
 * @param[in] address      IPv4 address to assign to this interface
 * @param[io] asyncResp    Response object that will be returned to client
 *
 * @return None
 */
inline void createHypervisorIPv4(
    const std::string& ifaceId, uint8_t prefixLength,
    const std::string& gateway, const std::string& address,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  setHypervisorIPv4Address(asyncResp, ifaceId, address);
  setHypervisorIPv4Gateway(asyncResp, gateway);
  setHypervisorIPv4Subnet(asyncResp, ifaceId, prefixLength);
}

/**
 * @brief Deletes given IPv4 interface
 *
 * @param[in] ifaceId     Id of interface whose IP should be deleted
 * @param[io] asyncResp   Response object that will be returned to client
 *
 * @return None
 */
inline void deleteHypervisorIPv4(
    const std::string& ifaceId,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  std::string address = "0.0.0.0";
  std::string gateway = "0.0.0.0";
  const uint8_t prefixLength = 0;
  setHypervisorIPv4Address(asyncResp, ifaceId, address);
  setHypervisorIPv4Gateway(asyncResp, gateway);
  setHypervisorIPv4Subnet(asyncResp, ifaceId, prefixLength);
}

inline void parseInterfaceData(
    nlohmann::json& jsonResponse, const std::string& ifaceId,
    const EthernetInterfaceData& ethData,
    const boost::container::flat_set<IPv4AddressData>& ipv4Data) {
  jsonResponse["Id"] = ifaceId;
  jsonResponse["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "Systems", "hypervisor", "EthernetInterfaces", ifaceId);
  jsonResponse["InterfaceEnabled"] = true;
  jsonResponse["MACAddress"] = ethData.macAddress;

  jsonResponse["HostName"] = ethData.hostName;
  jsonResponse["DHCPv4"]["DHCPEnabled"] =
      translateDhcpEnabledToBool(ethData.dhcpEnabled, true);

  nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"];
  nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"];
  ipv4Array = nlohmann::json::array();
  ipv4StaticArray = nlohmann::json::array();
  for (const auto& ipv4Config : ipv4Data) {
    if (ipv4Config.isActive) {
      nlohmann::json::object_t ipv4;
      ipv4["AddressOrigin"] = ipv4Config.origin;
      ipv4["SubnetMask"] = ipv4Config.netmask;
      ipv4["Address"] = ipv4Config.address;
      ipv4["Gateway"] = ethData.defaultGateway;

      if (ipv4Config.origin == "Static") {
        ipv4StaticArray.emplace_back(ipv4);
      }
      ipv4Array.emplace_back(std::move(ipv4));
    }
  }
}

inline void setDHCPEnabled(
    const std::string& ifaceId, const bool& ipv4DHCPEnabled,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  const std::string dhcp = getDhcpEnabledEnumeration(ipv4DHCPEnabled, false);
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
      },
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/network/hypervisor/" + ifaceId,
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Network.EthernetInterface", "DHCPEnabled",
      dbus::utility::DbusVariantType{dhcp});

  // Set the IPv4 address origin to the DHCP / Static as per the new value
  // of the DHCPEnabled property
  std::string origin;
  if (!ipv4DHCPEnabled) {
    origin = "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
  } else {
    // DHCPEnabled is set to true. Delete the current IPv4 settings
    // to receive the new values from DHCP server.
    deleteHypervisorIPv4(ifaceId, asyncResp);
    origin = "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
  }
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
        BMCWEB_LOG_DEBUG << "Hypervisor IPaddress Origin is Set";
      },
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/network/hypervisor/" + ifaceId + "/ipv4/addr0",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Network.IP", "Origin",
      dbus::utility::DbusVariantType(origin));
}

inline void handleHypervisorIPv4StaticPatch(
    const std::string& ifaceId, const nlohmann::json& input,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if ((!input.is_array()) || input.empty()) {
    messages::propertyValueTypeError(asyncResp->res, input.dump(),
                                     "IPv4StaticAddresses");
    return;
  }

  // Hypervisor considers the first IP address in the array list
  // as the Hypervisor's virtual management interface supports single IPv4
  // address
  const nlohmann::json& thisJson = input[0];

  if (!thisJson.is_null() && !thisJson.empty()) {
    // For the error string
    std::string pathString = "IPv4StaticAddresses/1";
    std::optional<std::string> address;
    std::optional<std::string> subnetMask;
    std::optional<std::string> gateway;
    nlohmann::json thisJsonCopy = thisJson;
    if (!json_util::readJson(thisJsonCopy, asyncResp->res, "Address", address,
                             "SubnetMask", subnetMask, "Gateway", gateway)) {
      messages::propertyValueFormatError(
          asyncResp->res,
          thisJson.dump(2, ' ', true, nlohmann::json::error_handler_t::replace),
          pathString);
      return;
    }

    uint8_t prefixLength = 0;
    bool errorInEntry = false;
    if (address) {
      if (!ip_util::ipv4VerifyIpAndGetBitcount(*address)) {
        messages::propertyValueFormatError(asyncResp->res, *address,
                                           pathString + "/Address");
        errorInEntry = true;
      }
    } else {
      messages::propertyMissing(asyncResp->res, pathString + "/Address");
      errorInEntry = true;
    }

    if (subnetMask) {
      if (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask, &prefixLength)) {
        messages::propertyValueFormatError(asyncResp->res, *subnetMask,
                                           pathString + "/SubnetMask");
        errorInEntry = true;
      }
    } else {
      messages::propertyMissing(asyncResp->res, pathString + "/SubnetMask");
      errorInEntry = true;
    }

    if (gateway) {
      if (!ip_util::ipv4VerifyIpAndGetBitcount(*gateway)) {
        messages::propertyValueFormatError(asyncResp->res, *gateway,
                                           pathString + "/Gateway");
        errorInEntry = true;
      }
    } else {
      messages::propertyMissing(asyncResp->res, pathString + "/Gateway");
      errorInEntry = true;
    }

    if (errorInEntry) {
      return;
    }

    BMCWEB_LOG_DEBUG << "Calling createHypervisorIPv4 on : " << ifaceId << ","
                     << *address;
    createHypervisorIPv4(ifaceId, prefixLength, *gateway, *address, asyncResp);
    // Set the DHCPEnabled to false since the Static IPv4 is set
    setDHCPEnabled(ifaceId, false, asyncResp);
  } else {
    if (thisJson.is_null()) {
      deleteHypervisorIPv4(ifaceId, asyncResp);
    }
  }
}

inline void handleHypervisorHostnamePatch(
    const std::string& hostName,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!isHostnameValid(hostName)) {
    messages::propertyValueFormatError(asyncResp->res, hostName, "HostName");
    return;
  }

  asyncResp->res.jsonValue["HostName"] = hostName;
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          messages::internalError(asyncResp->res);
        }
      },
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/hypervisor",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
      dbus::utility::DbusVariantType(hostName));
}

inline void setIPv4InterfaceEnabled(
    const std::string& ifaceId, const bool& isActive,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
      },
      "xyz.openbmc_project.Settings",
      "/xyz/openbmc_project/network/hypervisor/" + ifaceId + "/ipv4/addr0",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Object.Enable", "Enabled",
      dbus::utility::DbusVariantType(isActive));
}

inline void handleHypervisorEthernetInterfaceCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Network.EthernetInterface"};

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/xyz/openbmc_project/network/hypervisor", 0, interfaces, requestContext,
      [asyncResp](
          const boost::system::error_code& error,
          const dbus::utility::MapperGetSubTreePathsResponse& ifaceList) {
        if (error) {
          messages::resourceNotFound(asyncResp->res, "System", "hypervisor");
          return;
        }
        asyncResp->res.jsonValue["@odata.type"] =
            "#EthernetInterfaceCollection."
            "EthernetInterfaceCollection";
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
        asyncResp->res.jsonValue["Name"] =
            "Hypervisor Ethernet "
            "Interface Collection";
        asyncResp->res.jsonValue["Description"] =
            "Collection of Virtual Management "
            "Interfaces for the hypervisor";

        nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
        ifaceArray = nlohmann::json::array();
        for (const std::string& iface : ifaceList) {
          sdbusplus::message::object_path path(iface);
          std::string name = path.filename();
          if (name.empty()) {
            continue;
          }
          nlohmann::json::object_t ethIface;
          ethIface["@odata.id"] = crow::utility::urlFromPieces(
              "redfish", "v1", "Systems", "hypervisor", "EthernetInterfaces",
              name);
          ifaceArray.emplace_back(std::move(ethIface));
        }
        asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size();
      });
}

inline void handleHypervisorEthernetInterfaceGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& id) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  managedStore::ManagedObjectStoreContext context(asyncResp);
  getHypervisorIfaceData(
      id, context,
      [asyncResp, ifaceId{std::string(id)}](
          const bool& success, const EthernetInterfaceData& ethData,
          const boost::container::flat_set<IPv4AddressData>& ipv4Data) {
        if (!success) {
          messages::resourceNotFound(asyncResp->res, "EthernetInterface",
                                     ifaceId);
          return;
        }
        asyncResp->res.jsonValue["@odata.type"] =
            "#EthernetInterface.v1_6_0.EthernetInterface";
        asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet Interface";
        asyncResp->res.jsonValue["Description"] =
            "Hypervisor's Virtual Management Ethernet Interface";
        parseInterfaceData(asyncResp->res.jsonValue, ifaceId, ethData,
                           ipv4Data);
      });
}

inline void handleHypervisorSystemGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/hypervisor",
      "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
      requestContext,
      [asyncResp](const boost::system::error_code& ec,
                  const std::string& /*hostName*/) {
        if (ec) {
          messages::resourceNotFound(asyncResp->res, "System", "hypervisor");
          return;
        }
        BMCWEB_LOG_DEBUG << "Hypervisor is available";

        asyncResp->res.jsonValue["@odata.type"] =
            "#ComputerSystem.v1_6_0.ComputerSystem";
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Systems/hypervisor";
        asyncResp->res.jsonValue["Description"] = "Hypervisor";
        asyncResp->res.jsonValue["Name"] = "Hypervisor";
        asyncResp->res.jsonValue["Id"] = "hypervisor";
        asyncResp->res.jsonValue["SystemType"] = "OS";
        nlohmann::json::array_t managedBy;
        nlohmann::json::object_t manager;
        manager["@odata.id"] = "/redfish/v1/Managers/bmc";
        managedBy.emplace_back(std::move(manager));
        asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
        asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
            "/redfish/v1/Systems/hypervisor/EthernetInterfaces";
        getHypervisorState(asyncResp);
        getHypervisorActions(asyncResp);
        // TODO: Add "SystemType" : "hypervisor"
      });
}

inline void handleHypervisorEthernetInterfacePatch(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& ifaceId) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  std::optional<std::string> hostName;
  std::optional<std::vector<nlohmann::json>> ipv4StaticAddresses;
  std::optional<nlohmann::json> ipv4Addresses;
  std::optional<nlohmann::json> dhcpv4;
  std::optional<bool> ipv4DHCPEnabled;

  if (!json_util::readJsonPatch(req, asyncResp->res, "HostName", hostName,
                                "IPv4StaticAddresses", ipv4StaticAddresses,
                                "IPv4Addresses", ipv4Addresses, "DHCPv4",
                                dhcpv4)) {
    return;
  }

  if (ipv4Addresses) {
    messages::propertyNotWritable(asyncResp->res, "IPv4Addresses");
    return;
  }

  if (dhcpv4) {
    if (!json_util::readJson(*dhcpv4, asyncResp->res, "DHCPEnabled",
                             ipv4DHCPEnabled)) {
      return;
    }
  }
  managedStore::ManagedObjectStoreContext context(asyncResp);
  getHypervisorIfaceData(
      ifaceId, context,
      [asyncResp, ifaceId, hostName = std::move(hostName),
       ipv4StaticAddresses = std::move(ipv4StaticAddresses), ipv4DHCPEnabled,
       dhcpv4 = std::move(dhcpv4)](
          const bool& success, const EthernetInterfaceData& ethData,
          const boost::container::flat_set<IPv4AddressData>&) {
        if (!success) {
          messages::resourceNotFound(asyncResp->res, "EthernetInterface",
                                     ifaceId);
          return;
        }

        if (ipv4StaticAddresses) {
          const nlohmann::json& ipv4Static = *ipv4StaticAddresses;
          if (ipv4Static.begin() == ipv4Static.end()) {
            messages::propertyValueTypeError(
                asyncResp->res,
                ipv4Static.dump(2, ' ', true,
                                nlohmann::json::error_handler_t::replace),
                "IPv4StaticAddresses");
            return;
          }

          // One and only one hypervisor instance supported
          if (ipv4Static.size() != 1) {
            messages::propertyValueFormatError(
                asyncResp->res,
                ipv4Static.dump(2, ' ', true,
                                nlohmann::json::error_handler_t::replace),
                "IPv4StaticAddresses");
            return;
          }

          const nlohmann::json& ipv4Json = ipv4Static[0];
          // Check if the param is 'null'. If its null, it means
          // that user wants to delete the IP address. Deleting
          // the IP address is allowed only if its statically
          // configured. Deleting the address originated from DHCP
          // is not allowed.
          if ((ipv4Json.is_null()) &&
              (translateDhcpEnabledToBool(ethData.dhcpEnabled, true))) {
            BMCWEB_LOG_INFO << "Ignoring the delete on ipv4StaticAddresses "
                               "as the interface is DHCP enabled";
          } else {
            handleHypervisorIPv4StaticPatch(ifaceId, ipv4Static, asyncResp);
          }
        }

        if (hostName) {
          handleHypervisorHostnamePatch(*hostName, asyncResp);
        }

        if (dhcpv4) {
          setDHCPEnabled(ifaceId, *ipv4DHCPEnabled, asyncResp);
        }

        // Set this interface to disabled/inactive. This will be set
        // to enabled/active by the pldm once the hypervisor
        // consumes the updated settings from the user.
        setIPv4InterfaceEnabled(ifaceId, false, asyncResp);
      });
  asyncResp->res.result(boost::beast::http::status::accepted);
}

inline void handleHypervisorResetActionGet(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  // Only return action info if hypervisor D-Bus object present
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.State.Host"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getDbusObject(
      "/xyz/openbmc_project/state/hypervisor0", interfaces, requestContext,
      [asyncResp](
          const boost::system::error_code& ec,
          const std::vector<std::pair<std::string, std::vector<std::string>>>&
              objInfo) {
        if (ec) {
          BMCWEB_LOG_DEBUG << "DBUS response error " << ec;

          // No hypervisor objects found by mapper
          if (ec.value() == boost::system::errc::io_error) {
            messages::resourceNotFound(asyncResp->res, "hypervisor",
                                       "ResetActionInfo");
            return;
          }

          messages::internalError(asyncResp->res);
          return;
        }

        // One and only one hypervisor instance supported
        if (objInfo.size() != 1) {
          messages::internalError(asyncResp->res);
          return;
        }

        // The hypervisor object only support the ability to
        // turn On The system object Action should be utilized
        // for other operations

        asyncResp->res.jsonValue["@odata.type"] =
            "#ActionInfo.v1_1_2.ActionInfo";
        asyncResp->res.jsonValue["@odata.id"] =
            "/redfish/v1/Systems/hypervisor/ResetActionInfo";
        asyncResp->res.jsonValue["Name"] = "Reset Action Info";
        asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
        nlohmann::json::array_t parameters;
        nlohmann::json::object_t parameter;
        parameter["Name"] = "ResetType";
        parameter["Required"] = true;
        parameter["DataType"] = "String";
        nlohmann::json::array_t allowed;
        allowed.emplace_back("On");
        parameter["AllowableValues"] = std::move(allowed);
        parameters.emplace_back(std::move(parameter));
        asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
      });
}

inline void handleHypervisorSystemResetPost(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  std::optional<std::string> resetType;
  if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) {
    // readJson adds appropriate error to response
    return;
  }

  if (!resetType) {
    messages::actionParameterMissing(asyncResp->res, "ComputerSystem.Reset",
                                     "ResetType");
    return;
  }

  // Hypervisor object only support On operation
  if (resetType != "On") {
    messages::propertyValueNotInList(asyncResp->res, *resetType, "ResetType");
    return;
  }

  std::string command = "xyz.openbmc_project.State.Host.Transition.On";

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, resetType](const boost::system::error_code& ec) {
        if (ec) {
          BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
          if (ec.value() == boost::asio::error::invalid_argument) {
            messages::actionParameterNotSupported(asyncResp->res, *resetType,
                                                  "Reset");
            return;
          }

          if (ec.value() == boost::asio::error::host_unreachable) {
            messages::resourceNotFound(asyncResp->res, "Actions", "Reset");
            return;
          }

          messages::internalError(asyncResp->res);
          return;
        }
        messages::success(asyncResp->res);
      },
      "xyz.openbmc_project.State.Hypervisor",
      "/xyz/openbmc_project/state/hypervisor0",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.State.Host", "RequestedHostTransition",
      dbus::utility::DbusVariantType{std::move(command)});
}

inline void requestRoutesHypervisorSystems(App& app) {
  /**
   * HypervisorInterfaceCollection class to handle the GET and PATCH on
   * Hypervisor Interface
   */

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/hypervisor/EthernetInterfaces/")
      .privileges(redfish::privileges::getEthernetInterfaceCollection)
      .methods(boost::beast::http::verb::get)(std::bind_front(
          handleHypervisorEthernetInterfaceCollectionGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/hypervisor/EthernetInterfaces/<str>/")
      .privileges(redfish::privileges::getEthernetInterface)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleHypervisorEthernetInterfaceGet, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Systems/hypervisor/EthernetInterfaces/<str>/")
      .privileges(redfish::privileges::patchEthernetInterface)
      .methods(boost::beast::http::verb::patch)(std::bind_front(
          handleHypervisorEthernetInterfacePatch, std::ref(app)));

  BMCWEB_ROUTE(app,
               "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset/")
      .privileges(redfish::privileges::postComputerSystem)
      .methods(boost::beast::http::verb::post)(
          std::bind_front(handleHypervisorSystemResetPost, std::ref(app)));
}
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_HYPERVISOR_SYSTEM_H_
