#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_BOOTTIME_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_BOOTTIME_H_

#include <string_view>

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME
#include <charconv>
#include <cstdint>
#include <cstring>
#include <map>
#include <memory>
#include <optional>
#include <span>  // NOLINT
#include <string>
#include <system_error>  // NOLINT
#include <utility>
#include <vector>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"
#include "boottime_api/boottime_api.h"
#include "boottime_api/boottime_api_common.h"
#include "boottime_api/boottime_metrics.h"
#include "boottime_api/node_config.h"
#include "boottime_api/resource.h"
#include "time_utils.hpp"
#endif  // BMCWEB_ENABLE_REDFISH_BOOT_TIME

#include "async_resp.hpp"
#include "generated/enums/google_boot_time.hpp"
#include <nlohmann/json.hpp>

namespace redfish::boottime {

struct BootTimeResponseData {
  std::string_view oDataId;
  nlohmann::json::array_t breakdown;
  nlohmann::json::array_t durations;
  nlohmann::json::array_t checkpoints;
  double totalMs;
  bool isRebooting;
  google_boot_time::PowerSourceTypes powerType;
  nlohmann::json nodeUpTime;
  nlohmann::json nodeUpTimestamp;
  nlohmann::json loaderTimestamp;
  bool disabled;
  nlohmann::json warningMessage;
};

// A common API for populating BootTime data with a consistent schema.
inline void PopulateResponse(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const BootTimeResponseData& data) {
  asyncResp->res.jsonValue["@odata.type"] =
      "#GoogleBootTime.v1_0_0.GoogleBootTime";
  asyncResp->res.jsonValue["Name"] = "Boot time data";
  asyncResp->res.jsonValue["Id"] = "BootTimeData";
  asyncResp->res.jsonValue["@odata.type"] =
      "#GoogleBootTime.v1_0_0.GoogleBootTime";
  asyncResp->res.jsonValue["@odata.id"] = data.oDataId;
  asyncResp->res.jsonValue["Breakdown"] = data.breakdown;
  asyncResp->res.jsonValue["Durations"] = data.durations;
  asyncResp->res.jsonValue["RebootFlow"] = data.checkpoints;
  // Total is in seconds for Redfish.
  asyncResp->res.jsonValue["Total"] = data.totalMs / 1000.0;
  asyncResp->res.jsonValue["Stat"] = {
      {"PowerSource", data.powerType},
      {"IsRebooting", data.isRebooting},
      {"UpTime", data.nodeUpTime},
      {"UpTimestamp", data.nodeUpTimestamp},
      {"LoaderReadyTimestamp", data.loaderTimestamp},
  };
  asyncResp->res.jsonValue["Status"] = {
      {"State", data.disabled ? "Disabled" : "Enabled"},
      {"Health", "Ok"},
  };
  if (!data.warningMessage.is_null()) {
    asyncResp->res.jsonValue["Status"]["Health"] = "Warning";
    asyncResp->res.jsonValue["Status"]["Conditions"] = nlohmann::json::array();
    asyncResp->res.jsonValue["Status"]["Conditions"].push_back(
        data.warningMessage);
  }
}

// Populates the response with data indicating the BootTime feature is disabled.
inline void PopulateDisabledResponse(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    std::string_view oDataId) {
  BootTimeResponseData data = {};
  data.oDataId = oDataId;
  data.disabled = true;
  data.isRebooting = true;
  PopulateResponse(asyncResp, data);
}

inline nlohmann::json newWarningMessage(std::string_view message,
                                        std::string_view resolution) {
  return {
      {"MessageId", "Base.1.13.0.ResourceNotFound"},
      {"Message", message},
      {"Severity", "Warning"},
      {"Resolution", resolution},
  };
}

#ifdef BMCWEB_ENABLE_REDFISH_BOOT_TIME

using boot_time_monitor::resource::FileResource;
using boot_time_monitor::type::Checkpoint;
using boot_time_monitor::type::CheckpointEntry;
using boot_time_monitor::type::Duration;
using boot_time_monitor::type::DurationEntry;
using boot_time_monitor::type::NamedDurationsMs;

// Import default values here for mocking.
inline std::string_view kLockFile = boot_time_monitor::def::kLockFile;
inline std::string_view kDataDir = boot_time_monitor::def::kDataDir;

inline std::vector<CheckpointEntry> ToCheckpointEntry(
    std::span<const Checkpoint> inputTuples) {
  std::vector<CheckpointEntry> checkpoints;
  checkpoints.reserve(inputTuples.size());
  for (const auto& t : inputTuples) {
    checkpoints.push_back(CheckpointEntry(t));
  }

  return checkpoints;
}

inline std::vector<DurationEntry> ToDurationEntry(
    std::span<const Duration> inputTuples) {
  std::vector<DurationEntry> durations;
  durations.reserve(inputTuples.size());
  for (const auto& t : inputTuples) {
    durations.push_back(DurationEntry(t));
  }
  return durations;
}

inline nlohmann::json::array_t ConvertToJson(const NamedDurationsMs& stages) {
  nlohmann::json::array_t ret = nlohmann::json::array();
  for (const auto& [name, duration] : stages) {
    nlohmann::json::object_t breakdownEntry;
    breakdownEntry["Stage"] = name;
    breakdownEntry["Duration"] = static_cast<double>(duration) / 1000.0;
    ret.push_back(breakdownEntry);
  }
  return ret;
}

inline nlohmann::json::array_t ConvertToJson(
    std::span<const CheckpointEntry> checkpoints) {
  nlohmann::json::array_t ret = nlohmann::json::array();
  for (const auto& checkpoint : checkpoints) {
    nlohmann::json::object_t checkpointEntry;
    checkpointEntry["Stage"] = checkpoint.name;
    checkpointEntry["StartTime"] = time_utils::getDateTimeUintMs(
        static_cast<uint64_t>(checkpoint.wall_time_ms));
    checkpointEntry["MonotonicStartTime"] = checkpoint.monotonic_time_ms;
    ret.push_back(checkpointEntry);
  }
  return ret;
}

inline nlohmann::json::array_t ConvertToJson(
    std::span<const DurationEntry> durations) {
  nlohmann::json::array_t ret = nlohmann::json::array();
  for (const auto& duration : durations) {
    nlohmann::json::object_t durationEntry;
    durationEntry["Name"] = duration.name;
    durationEntry["Duration"] = static_cast<double>(duration.duration_ms) /
                                1000.0;  // Convert ms to seconds
    ret.push_back(durationEntry);
  }
  return ret;
}

/**
 * @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"). On success, the `index` parameter
 * is set to the corresponding 0-based index (N-1).
 *
 * In a single-host configuration (`multihost` is `false`), this function
 * expects the system name to be exactly "system". On success, the `index`
 * parameter is set to `0`.
 *
 * @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) {
    // The system name should just be "system" in single host.
    if (systemName == "system") {
      return 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.");
}

inline google_boot_time::PowerSourceTypes GetPowerType(
    std::span<const CheckpointEntry> checkpoints) {
  if (checkpoints.empty()) {
    return google_boot_time::PowerSourceTypes::Unknown;
  }
  if (boot_time_monitor::metrics::PowerCycleCount(checkpoints) > 0) {
    return google_boot_time::PowerSourceTypes::AC;
  }
  return google_boot_time::PowerSourceTypes::DC;
}

/**
 * @brief Populates Redfish BootTime data for a given node.
 *
 * This function retrieves boot time data (checkpoints, durations) from
 * the boot time monitor API, processes it based on the node's tag (Host or
 * BMC), and populates the asynchronous Redfish response with the structured
 * data.
 *
 * @param asyncResp A shared pointer to the bmcweb::AsyncResp object for
 * populating the Redfish response.
 * @param oDataId   The OData ID string for the Redfish resource.
 * @param node      The boot_time_monitor::NodeConfig specifying the target
 * node.
 * @return An `absl::Status` indicating success or failure.
 */
inline absl::Status PopulateBootTimeData(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    std::string_view oDataId, boot_time_monitor::NodeConfig node) {
  boot_time_monitor::api::BoottimeApi api(kLockFile, absl::Seconds(5));
  auto file = std::make_unique<FileResource>(node.node_name, kDataDir);
  absl::Status status = api.RegisterNode(node, std::move(file));
  if (status.code() != absl::StatusCode::kOk &&
      status.code() != absl::StatusCode::kAlreadyExists) {
    return absl::InternalError(
        absl::StrCat("Failed to register ", node.node_name,
                     " node due to internal error: ", status.ToString()));
  }

  NamedDurationsMs breakdown;
  auto checkpoints = ToCheckpointEntry(api.GetNodeCheckpointList(node));
  auto durations = ToDurationEntry(api.GetNodeAdditionalDurations(node));
  bool isRebooting = api.IsNodeRebooting(node);
  std::optional<int64_t> nodeUpTime =
      boot_time_monitor::metrics::ParseNodeUpTimeMs(checkpoints);
  std::optional<int64_t> nodeUpTimestamp =
      boot_time_monitor::metrics::ParseNodeUpTimestamp(checkpoints);
  std::optional<int64_t> loaderTimestamp =
      boot_time_monitor::metrics::ParseLastLoaderTimestamp(checkpoints);
  double totalMs = 0.0;

  if (checkpoints.empty()) {
    BootTimeResponseData data = {};
    data.oDataId = oDataId;
    data.warningMessage = newWarningMessage(
        "Checkpoints is empty.",
        "Please check if host/bmc sends checkpoints correctly.");
    data.isRebooting = true;
    PopulateResponse(asyncResp, data);
    return absl::OkStatus();
  }

  if (node.tag == boot_time_monitor::kBootTimeTagHost) {
    breakdown = boot_time_monitor::metrics::ParseHostRebootStages(checkpoints);
    // Make sure kernel stage always present.
    boot_time_monitor::metrics::UpdateKernelStageDuration(breakdown, durations);
    totalMs = boot_time_monitor::metrics::GetTotalRebootTime(
        checkpoints.front(), checkpoints.back(), durations);
    // Update Off stage duration by using total time.
    boot_time_monitor::metrics::UpdateHostOffStageDuration(breakdown, totalMs);
  } else if (node.tag == boot_time_monitor::kBootTimeTagBMC) {
    breakdown = boot_time_monitor::metrics::ParseBMCRebootStages(checkpoints);
    totalMs = boot_time_monitor::metrics::GetTotalRebootTime(
        checkpoints.front(), checkpoints.back(), durations);
  } else {
    return absl::NotFoundError(
        absl::StrCat("Invalid node tag(type): ", node.tag));
  }

  BootTimeResponseData data = {};
  data.oDataId = oDataId;
  data.breakdown = ConvertToJson(breakdown);
  data.durations = ConvertToJson(durations);
  data.checkpoints = ConvertToJson(checkpoints);
  data.totalMs = totalMs;
  data.powerType = GetPowerType(checkpoints);
  data.isRebooting = isRebooting;
  data.nodeUpTime = nodeUpTime.has_value() ? nlohmann::json(nodeUpTime.value())
                                           : nlohmann::json();
  data.nodeUpTimestamp = nodeUpTimestamp.has_value()
                             ? nlohmann::json(nodeUpTimestamp.value())
                             : nlohmann::json();
  data.loaderTimestamp = loaderTimestamp.has_value()
                             ? nlohmann::json(loaderTimestamp.value())
                             : nlohmann::json();

  PopulateResponse(asyncResp, data);
  return absl::OkStatus();
}

/**
 * @brief Populates Redfish BootTime data for a specific host system.
 *
 * This function determines the host index from the system name, constructs
 * the appropriate node configuration for the host, and then calls
 * PopulateBootTimeData to retrieve and populate the Redfish response.
 *
 * @param asyncResp   A shared pointer to the bmcweb::AsyncResp object.
 * @param systemName  The name of the system (e.g., "system", "system1").
 * @param objects     A vector of strings, representing dbus objects under
 * the system.
 * @return An `absl::Status` indicating success or failure.
 */
inline absl::Status PopulateHostData(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& systemName, const std::vector<std::string>& objects) {
  bool isMultiHost = (objects.size() != 1);
  absl::StatusOr<size_t> idx = parseSystemNameToIndex(systemName, isMultiHost);
  std::string oDataId =
      absl::StrCat("/redfish/v1/Systems/", systemName, "/Oem/Google/BootTime");

  if (!idx.ok() || *idx >= objects.size()) {
    BootTimeResponseData data = {};
    data.oDataId = oDataId;
    data.warningMessage =
        newWarningMessage(absl::StrCat("Invalid systemName index: ", systemName,
                                       ". Error: ", idx.status().ToString()),
                          "Please assign correct system index.");
    data.isRebooting = true;
    PopulateResponse(asyncResp, data);
    return absl::OkStatus();
  }

  boot_time_monitor::NodeConfig node = {
      .node_name = "host" + std::to_string(*idx),
      .tag = std::string(boot_time_monitor::kBootTimeTagHost),
  };
  return PopulateBootTimeData(asyncResp, oDataId, node);
}

/**
 * @brief Populates Redfish BootTime data for the BMC.
 *
 * This function constructs the node configuration for the BMC and then calls
 * PopulateBootTimeData to retrieve and populate the Redfish response.
 *
 * @param asyncResp A shared pointer to the bmcweb::AsyncResp object.
 * @return An `absl::Status` indicating success or failure.
 */
inline absl::Status PopulateBmcData(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  boot_time_monitor::NodeConfig node = {
      .node_name = "bmc",
      .tag = std::string(boot_time_monitor::kBootTimeTagBMC),
  };

  return PopulateBootTimeData(
      asyncResp, "/redfish/v1/Managers/bmc/Oem/Google/BootTime", node);
}

#endif  // BMCWEB_ENABLE_REDFISH_BOOT_TIME
}  // namespace redfish::boottime

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_INCLUDE_UTILS_BOOTTIME_H_
