#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 "system_utils.hpp"  // IWYU pragma: keep
#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;
}

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 =
      system_utils::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_
