#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_SYSTEM_UTILS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_SYSTEM_UTILS_H_

#include <array>
#include <charconv>
#include <cstddef>
#include <memory>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT
#include <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "boost/system/error_code.hpp"  // NOLINT
#include "logging.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"

namespace redfish {
namespace system_utils {

constexpr std::array<std::string_view, 1> systemInterfaces{
    {"xyz.openbmc_project.Inventory.Item.System"}};

/**
 * @brief Checks whether single-system fallback logic should be triggered based on
 * enumerated system D-Bus objects count.
 */
inline bool isHardcodedSingleHost(
    [[maybe_unused]] const size_t systemObjectsCount) {
#ifdef BMCWEB_ALLOW_NON_HARDCODED_SINGLEHOST_SYSTEM
  return false;
#else
  return systemObjectsCount < 2;
#endif
}

template <typename Callback>
inline void findSystemPathAndTriggerCallback(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName,
    const dbus::utility::MapperGetSubTreePathsResponse& objects,
    Callback&& callback) {
  if (isHardcodedSingleHost(objects.size())) {
    if (systemName != "system") {
      messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
      return;
    }
    callback(asyncResp, "");
    return;
  }
  // Otherwise find system
  for (const auto& object : objects) {
    std::string objectName = sdbusplus::message::object_path(object).filename();
    // Found system object
    if (systemName == objectName) {
      callback(asyncResp, object);
      return;
    }
  }
  // Could not find system object
  messages::resourceNotFound(asyncResp->res, "ComputerSystem", systemName);
}
/**
 * @brief Retrieves valid system path
 * @param asyncResp   Pointer to object holding response data
 * @param callback  Callback for next step to get valid system path
 * Callback should take in asyncResp pointer and full object path of Item.System
 * Single Host Systems will return empty string as the object path of
 * Item.System.
 */
template <typename Callback>
void getSystemInformation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& systemName, Callback&& callback) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [callback{std::forward<Callback>(callback)}, asyncResp, systemName](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& objects) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
        findSystemPathAndTriggerCallback(asyncResp, systemName, objects,
                                         callback);
      });
}

template <typename Callback>
void getAllSystems(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                   Callback&& callback) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTreePaths(
      "/", 0, systemInterfaces, requestContext,
      [callback{std::forward<Callback>(callback)}, asyncResp](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreePathsResponse& objects) {
        if (ec) {
          BMCWEB_LOG_ERROR << "DBUS response error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }
        callback(asyncResp, objects);
      });
}

inline std::string getSystemName(const std::string& systemPath) {
  // If the systemPath is empty, then the system is single host
  bool multiHost = !systemPath.empty();

  // Default systemName is system
  if (!multiHost) {
    return "system";
  }

  return sdbusplus::message::object_path(systemPath).filename();
}

/**
 * @brief Parses a system name to determine its corresponding host index.
 *
 * This function validates and extracts a host index from a system name string,
 * adjusting its behavior based on whether the system is in a multihost
 * configuration.
 *
 * In a multihost configuration (`multihost` is `true`), this function expects
 * the system name to be in the format "system<N>", where <N> is a 1-based
 * integer (e.g., "system1", "system2").
 *
 * In a single-host configuration (`multihost` is `false`), if
 * allow-non-hardcoded-singlehost-system is disabled, this function expects the system name to be
 * exactly "system"; on success, the `index` parameter is set to `0`.
 * If allow-non-hardcoded-singlehost-system is enabled, this function expects the system name to
 * be "system" or "system<N>"; on success, the `index` parameter is set to the
 * corresponding 0-based index (N-1) or 0 for "system".
 *
 * @param systemName The system name string to parse (e.g., "system1").
 * @param multihost  A flag indicating if the system is in a
 * multihost environment.
 * @return An `absl::StatusOr<size_t>` containing the parsed 0-based host index
 * if successful, or an `absl::Status` with an error otherwise.
 */
inline absl::StatusOr<size_t> parseSystemNameToIndex(
    const std::string_view systemName, const bool multihost) {
  if (!multihost) {
    // 0 if systemName is system in single host.
    if (systemName == "system") {
      return 0;
    }
    if (isHardcodedSingleHost(0)) {
      return absl::NotFoundError(absl::StrCat(
          "Invalid single node machine system name: ", systemName));
    }
  }

  constexpr std::string_view prefix = "system";

  if (systemName.size() < prefix.size() ||
      systemName.substr(0, prefix.size()) != prefix) {
    return absl::NotFoundError(
        "system name must start with 'system' but got: " +
        std::string(systemName));
  }

  std::string_view number_part = systemName.substr(prefix.length());

  if (number_part.empty()) {
    return absl::NotFoundError(
        "system name must has index on multi-node machines.");
  }

  size_t number = 0;
  const auto result = std::from_chars(
      number_part.data(), number_part.data() + number_part.size(), number);

  if (result.ec == std::errc() &&
      result.ptr == number_part.data() + number_part.size()) {
    if (number > 0) {
      return number - 1;  // System names are 1-based, index is 0-based
    }
  }

  return absl::NotFoundError(
      "system index parsing failed or number was not a positive integer.");
}
}  // namespace system_utils
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_SYSTEM_UTILS_H_
