#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_RESPONSE_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_RESPONSE_H_

#include <memory>
#include <string>
#include <string_view>
#include <utility>

#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "boost/beast/http/string_body.hpp"  //NOLINT
#include "redfish_v1.pb.h"
#include "grpcpp/support/server_callback.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"
#include "dbus_utility.hpp" // NOLINT
#include "async_resp.hpp" // NOLINT
#include "http_request.hpp" // NOLINT

namespace milotic_tlbmc {

// The class is thread-compatible.
class RedfishResponse {
 public:
  RedfishResponse(grpc::ServerUnaryReactor* reactor,
                  redfish::v1::Response& grpc_response);
  RedfishResponse() = default;
  RedfishResponse(RedfishResponse&&) = default;
  RedfishResponse& operator=(RedfishResponse&&) = delete;
  RedfishResponse(const RedfishResponse&) = delete;
  RedfishResponse& operator=(const RedfishResponse&) = delete;

  void End();

  // Sets a value in the json body at the given key.
  template <typename ValueType>
  void SetKeyInJsonBody(const nlohmann::json::json_pointer& key,
                        const ValueType& value) {
    json_body_[key] = value;
  }

  // Convenience function for setting a value in the json body.
  // Creates json pointer from a given string key and passes to above function.
  template <typename ValueType>
  void SetKeyInJsonBody(const std::string& key, const ValueType& value) {
    nlohmann::json::json_pointer key_pointer(key);
    SetKeyInJsonBody(key_pointer, value);
  }

  // Appends a value to the array object at the given key in the json body.
  // If there is no existing array object at key, this function will create one.
  template <typename ValueType>
  void AppendToKeyInJsonBody(const nlohmann::json::json_pointer& key,
                             const ValueType& value) {
    json_body_[key].push_back(value);
  }

  // Convenience function for appending a value to an array object in json body.
  // Creates json pointer from a given string key and passes to above function.
  template <typename ValueType>
  void AppendToKeyInJsonBody(const std::string& key, const ValueType& value) {
    nlohmann::json::json_pointer key_pointer(key);
    AppendToKeyInJsonBody(key_pointer, value);
  }

  void SetHeader(std::string_view key, std::string_view value);

  void SetBinaryBody(std::string_view body);

  void SetBodyToJson();

  void SetBodyToOctetStream();

  void SetToNotFound(std::string_view error_message);

  void SetToForbidden(std::string_view error_message);

  void SetToAbslStatus(const absl::Status& status);

  // Key here is the unique identifier of the resource that is not ready.
  void SetToNotReady(std::string_view error_message);

  std::string DebugString() const { return absl::StrCat(*grpc_response_); }

  const nlohmann::json& GetJsonBody() const { return json_body_; }

  boost::beast::http::status GetHttpResponseStatus() {
    return http_response_.result();
  }

  void SetAsyncResp(std::shared_ptr<bmcweb::AsyncResp> async_resp) {
    async_resp_ = std::move(async_resp);
  }

  std::shared_ptr<bmcweb::AsyncResp> ReleaseAsyncResp() {
    return std::move(async_resp_);
  }

  void SetErrorMessage(const nlohmann::json& error_message_json);

 private:
  grpc::ServerUnaryReactor* reactor_ = nullptr;
  redfish::v1::Response* grpc_response_ = nullptr;
  nlohmann::json json_body_;
  boost::beast::http::response<boost::beast::http::string_body> http_response_;
  std::shared_ptr<bmcweb::AsyncResp> async_resp_;
  bool end_called_ = false;
};

}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_REDFISH_RESPONSE_H_
