#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_ENVIRONMENT_METRICS_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_ENVIRONMENT_METRICS_H_

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <functional>

#include "app.hpp"
#include "http_request.hpp"
#include "utility.hpp"
#include "async_resp.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "error_messages.hpp"
#include "chassis_utils.hpp"

namespace redfish {

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

  auto respHandler = [asyncResp, chassisId](
                         const std::optional<std::string>& validChassisPath) {
    if (!validChassisPath) {
      messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
      return;
    }

    asyncResp->res.addHeader(boost::beast::http::field::link,
                             "</redfish/v1/JsonSchemas/EnvironmentMetrics/"
                             "EnvironmentMetrics.json>; rel=describedby");
  };

  redfish::chassis_utils::getValidChassisPath(asyncResp, chassisId,
                                              std::move(respHandler));
}

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

  auto respHandler = [asyncResp, chassisId](
                         const std::optional<std::string>& validChassisPath) {
    if (!validChassisPath) {
      messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
      return;
    }

    asyncResp->res.addHeader(boost::beast::http::field::link,
                             "</redfish/v1/JsonSchemas/EnvironmentMetrics/"
                             "EnvironmentMetrics.json>; rel=describedby");
    asyncResp->res.jsonValue["@odata.type"] =
        "#EnvironmentMetrics.v1_3_0.EnvironmentMetrics";
    asyncResp->res.jsonValue["Name"] = "Chassis Environment Metrics";
    asyncResp->res.jsonValue["Id"] = "EnvironmentMetrics";
    asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
        "redfish", "v1", "Chassis", chassisId, "EnvironmentMetrics");
  };

  redfish::chassis_utils::getValidChassisPath(asyncResp, chassisId,
                                              std::move(respHandler));
}

inline void requestRoutesEnvironmentMetrics(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/EnvironmentMetrics/")
      .privileges(redfish::privileges::headEnvironmentMetrics)
      .methods(boost::beast::http::verb::head)(
          std::bind_front(handleEnvironmentMetricsHead, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/EnvironmentMetrics/")
      .privileges(redfish::privileges::getEnvironmentMetrics)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleEnvironmentMetricsGet, std::ref(app)));
}

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_ENVIRONMENT_METRICS_H_
