#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 "async_resp.hpp"
#include "grpcpp/support/server_callback.h"
#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"

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 SetToAccepted(std::string_view location);

  void SetToNotFound(std::string_view error_message);

  void SetToForbidden(std::string_view error_message);

  void SetToInternalError(std::string_view error_message);

  void SetToConflict(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_
