#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_METRIC_REPORT_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_METRIC_REPORT_H_

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

#include "app.hpp"
// #include "dbus_utility.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "error_messages.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "collection.hpp"
#include "dbus_utils.hpp"
#include "telemetry_utils.hpp"
#include "time_utils.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"

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

namespace redfish {

namespace telemetry {

using Readings =
    std::vector<std::tuple<std::string, std::string, double, uint64_t>>;
using TimestampReadings = std::tuple<uint64_t, Readings>;

inline nlohmann::json toMetricValues(const Readings& readings) {
  nlohmann::json metricValues = nlohmann::json::array_t();

  for (const auto& [id, metadata, sensorValue, timestamp] : readings) {
    nlohmann::json::object_t metricReport;
    metricReport["MetricId"] = id;
    metricReport["MetricProperty"] = metadata;
    metricReport["MetricValue"] = std::to_string(sensorValue);
    metricReport["Timestamp"] =
        redfish::time_utils::getDateTimeUintMs(timestamp);
    metricValues.push_back(std::move(metricReport));
  }

  return metricValues;
}

inline bool fillReport(nlohmann::json& json, const std::string& id,
                       const TimestampReadings& timestampReadings) {
  json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport";
  json["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "TelemetryService", "MetricReports", id);
  json["Id"] = id;
  json["Name"] = id;
  json["MetricReportDefinition"]["@odata.id"] = crow::utility::urlFromPieces(
      "redfish", "v1", "TelemetryService", "MetricReportDefinitions", id);

  const auto& [timestamp, readings] = timestampReadings;
  json["Timestamp"] = redfish::time_utils::getDateTimeUintMs(timestamp);
  json["MetricValues"] = toMetricValues(readings);
  return true;
}
}  // namespace telemetry

inline void handleMetricReportCollectionGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }

  asyncResp->res.jsonValue["@odata.type"] =
      "#MetricReportCollection.MetricReportCollection";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/TelemetryService/MetricReports";
  asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
  constexpr std::array<std::string_view, 1> interfaces{
      telemetry::reportInterface};
  collection_util::getCollectionMembers(
      asyncResp, boost::urls::url("/redfish/v1/TelemetryService/MetricReports"),
      interfaces, "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
}

inline void requestRoutesMetricReportCollection(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/")
      .privileges(redfish::privileges::getMetricReportCollection)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleMetricReportCollectionGet, std::ref(app)));
}

inline void handleMetricReportGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& id) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  const std::string reportPath = telemetry::getDbusReportPath(id);
  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp, id, reportPath](const boost::system::error_code& ec) {
        if (ec.value() == EBADR ||
            ec == boost::system::errc::host_unreachable) {
          messages::resourceNotFound(asyncResp->res, "MetricReport", id);
          return;
        }
        if (ec) {
          BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
          messages::internalError(asyncResp->res);
          return;
        }

        managedStore::ManagedObjectStoreContext requestContext(asyncResp);
        dbus_utils::getProperty<telemetry::TimestampReadings>(
            telemetry::service, reportPath, telemetry::reportInterface,
            "Readings", requestContext,
            [asyncResp, id](const boost::system::error_code& ec2,
                            const telemetry::TimestampReadings& ret) {
              if (ec2) {
                BMCWEB_LOG_ERROR << "respHandler DBus error " << ec2;
                messages::internalError(asyncResp->res);
                return;
              }

              telemetry::fillReport(asyncResp->res.jsonValue, id, ret);
            });
      },
      telemetry::service, reportPath, telemetry::reportInterface, "Update");
}

inline void requestRoutesMetricReport(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/")
      .privileges(redfish::privileges::getMetricReport)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleMetricReportGet, std::ref(app)));
}
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_METRIC_REPORT_H_
