#ifndef THIRD_PARTY_GBMCWEB_HTTP_HTTP_RESPONSE_H_
#define THIRD_PARTY_GBMCWEB_HTTP_HTTP_RESPONSE_H_

#include <cstdint>
#include <functional>
#include <map>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "boost/beast/http/message.hpp"  // NOLINT
#include "boost/beast/http/string_body.hpp"  // NOLINT
#include "subscription.h"
#include <nlohmann/json.hpp>

namespace crow {

template <typename Adaptor, typename Handler>
class Connection;

struct Response {
  template <typename Adaptor, typename Handler>
  friend class crow::Connection;
  using response_type =
      boost::beast::http::response<boost::beast::http::string_body>;

  std::optional<response_type> stringResponse;  // NOLINT

  nlohmann::json jsonValue;  // NOLINT

  // Identifiers for redfish event sources.
  // Used in event subscription sequence only.
  std::vector<ecclesia::EventSourceId> eventSourceIds;  // NOLINT

  void addHeader(std::string_view key, std::string_view value) {
    stringResponse->set(key, value);
  }

  void addHeader(boost::beast::http::field key, std::string_view value) {
    stringResponse->set(key, value);
  }

  Response() : stringResponse(response_type{}) {}

  Response(Response&& res) noexcept
      : stringResponse(std::move(res.stringResponse)),
        jsonValue(std::move(res.jsonValue)),
        completed(res.completed) {
    // See note in operator= move handler for why this is needed.
    if (!res.completed) {
      completeRequestHandler = std::move(res.completeRequestHandler);
      res.completeRequestHandler = nullptr;
    }
    isAliveHelper = res.isAliveHelper;
    res.isAliveHelper = nullptr;
  }

  virtual ~Response() = default;

  Response(const Response&) = delete;

  Response& operator=(const Response& r) = delete;

  Response& operator=(Response&& r) noexcept;

  void result(unsigned v) { stringResponse->result(v); }

  void result(boost::beast::http::status v) { stringResponse->result(v); }

  boost::beast::http::status result() const { return stringResponse->result(); }

  unsigned resultInt() const { return stringResponse->result_int(); }
  std::string_view reason() const { return stringResponse->reason(); }

  bool isCompleted() const noexcept { return completed; }

  std::string& body() { return stringResponse->body(); }

  std::string_view getHeaderValue(std::string_view key) const {
    return stringResponse->base()[key];
  }

  void keepAlive(bool k) { stringResponse->keep_alive(k); }

  bool keepAlive() const { return stringResponse->keep_alive(); }

  void preparePayload() { stringResponse->prepare_payload(); }

  void clear();

  void write(std::string_view bodyPart) {
    stringResponse->body() += std::string(bodyPart);
  }

  std::string computeEtag() const;

  void end();

  bool isAlive() const { return isAliveHelper && isAliveHelper(); }

  void setCompleteRequestHandler(std::function<void(Response&)>&& handler);

  std::function<void(Response&)> releaseCompleteRequestHandler();

  void setIsAliveHelper(std::function<bool()>&& handler) {
    isAliveHelper = std::move(handler);
  }

  std::function<bool()> releaseIsAliveHelper() {
    std::function<bool()> ret = std::move(isAliveHelper);
    isAliveHelper = nullptr;
    return ret;
  }

  void setHashAndHandleNotModified();

  void setExpectedHash(std::string_view hash) { expectedHash = hash; }

  void startTimetrace(const std::string& block);
  void endTimetrace(const std::string& block);
  void requestStartTime(const std::string& uri);
  void requestEndTime();
  nlohmann::json timetraceToJson();
  void updateTraceInManagedStore();

 private:
  void addTimetrace(const std::string& marker);
  std::optional<std::string> expectedHash;  // NOLINT
  bool completed = false;
  std::function<void(Response&)> completeRequestHandler;  // NOLINT
  std::map<std::string, int64_t> markers;
  std::function<bool()> isAliveHelper;  // NOLINT
};
}  // namespace crow
#endif  // THIRD_PARTY_GBMCWEB_HTTP_HTTP_RESPONSE_H_
