#include "http_response.hpp"

#include <chrono>  // NOLINT
#include <cstddef>
#include <functional>
#include <optional>
#include <string>
#include <utility>

#include "absl/strings/match.h"
#include "boost/algorithm/string/case_conv.hpp"  // NOLINT
#include "logging.hpp"
#include "hex_utils.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"

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

namespace crow {

Response& Response::operator=(Response&& r) noexcept {
  BMCWEB_LOG_DEBUG << "Moving response containers; this: " << this
                   << "; other: " << &r;
  if (this == &r) {
    return *this;
  }
  stringResponse = std::move(r.stringResponse);
  r.stringResponse.emplace(response_type{});
  jsonValue = std::move(r.jsonValue);

  for (const auto& [marker, timestamp] : r.markers) {
    markers.emplace(marker, timestamp);
  }

  // Only need to move completion handler if not already completed
  // Note, there are cases where we might move out of a Response object
  // while in a completion handler for that response object.  This check
  // is intended to prevent destructing the functor we are currently
  // executing from in that case.
  if (!r.completed) {
    completeRequestHandler = std::move(r.completeRequestHandler);
    r.completeRequestHandler = nullptr;
  } else {
    completeRequestHandler = nullptr;
  }
  completed = r.completed;
  isAliveHelper = std::move(r.isAliveHelper);
  r.isAliveHelper = nullptr;
  return *this;
}

void Response::clear() {
  BMCWEB_LOG_DEBUG << this << " Clearing response containers";
  stringResponse.emplace(response_type{});
  jsonValue.clear();
  completed = false;
  expectedHash = std::nullopt;
}

std::string Response::computeEtag() const {
  // return empty string if we don't have a string response
  if (!stringResponse.has_value()) {
    return "";
  }
  // Only set etag if this request succeeded
  if (result() != boost::beast::http::status::ok) {
    return "";
  }
  // and the json response isn't empty
  if (jsonValue.empty()) {
    return "";
  }
  size_t hashval = std::hash<nlohmann::json>{}(jsonValue);
  return "\"" + intToHexString(hashval, 8) + "\"";
}

void Response::setHashAndHandleNotModified() {
  // Can only hash if we have content that's valid
  if (jsonValue.empty() || result() != boost::beast::http::status::ok) {
    return;
  }
  size_t hashval = std::hash<nlohmann::json>{}(jsonValue);
  std::string hex_val = "\"" + intToHexString(hashval, 8) + "\"";
  addHeader(boost::beast::http::field::etag, hex_val);
  if (expectedHash && hex_val == *expectedHash) {
    jsonValue.clear();
    result(boost::beast::http::status::not_modified);
  }
}

void Response::end() {
  std::string etag = computeEtag();
  if (!etag.empty()) {
    addHeader(boost::beast::http::field::etag, etag);
  }
  if (completed) {
    BMCWEB_LOG_ERROR << this << " Response was ended twice";
    return;
  }
  completed = true;
  BMCWEB_LOG_DEBUG << this << " calling completion handler";
  if (completeRequestHandler) {
    BMCWEB_LOG_DEBUG << this << " completion handler was valid";
    completeRequestHandler(*this);
  }
}

void Response::setCompleteRequestHandler(
    std::function<void(Response&)>&& handler) {
  completeRequestHandler = std::move(handler);
  BMCWEB_LOG_DEBUG << this << " setting completion handler"
                   << &completeRequestHandler;
  // Now that we have a new completion handler attached, we're no longer
  // complete
  completed = false;
}

std::function<void(Response&)> Response::releaseCompleteRequestHandler() {
  BMCWEB_LOG_DEBUG << this << " releasing completion handler"
                   << &completeRequestHandler;
  std::function<void(Response&)> ret = completeRequestHandler;
  completeRequestHandler = nullptr;
  completed = true;
  return ret;
}

void Response::addTimetrace(const std::string& marker) {
  if (managedStore::GetManagedObjectStore()->getConfig().timetrace) {
    std::chrono::high_resolution_clock::time_point now =
        std::chrono::high_resolution_clock::now();
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                  now.time_since_epoch())
                  .count();
    markers[marker] = ms;
  }
}

void Response::startTimetrace(const std::string& block) {
  addTimetrace("START_" + block);
}

void Response::endTimetrace(const std::string& block) {
  addTimetrace("END_" + block);
}

void Response::requestStartTime(const std::string& uri) {
  addTimetrace("REQUEST_" + uri);
}
void Response::requestEndTime() { addTimetrace("REQUESTEND"); }

nlohmann::json Response::timetraceToJson() {
  nlohmann::json json_obj;
  if (managedStore::GetManagedObjectStore()->getConfig().timetrace) {
    nlohmann::json& hops = json_obj["hops"];
    hops = nlohmann::json::array();
    for (const auto& [marker, timestamp] : markers) {
      if (absl::StrContains(marker, "START_")) {
        continue;
      }
      // process END_
      size_t pos = marker.find("END_");
      if (pos != std::string::npos) {
        // find the start and calculate the diff
        std::string block = marker.substr(pos + 4);
        auto start_time = markers["START_" + block];
        auto duration = timestamp - start_time;
        nlohmann::json::object_t hop;
        hop["id"] = boost::algorithm::to_lower_copy(block);
        hop["time_ms"] = duration;
        hops.emplace_back(std::move(hop));
      } else if (absl::StrContains(marker, "REQUEST_")) {
        size_t uri_pos = marker.find("REQUEST_");
        std::string uri = marker.substr(uri_pos + 8);
        json_obj["uri"] = uri;
        json_obj["starttime"] = timestamp;
      } else if (absl::StrContains(marker, "REQUESTEND")) {
        json_obj["endtime"] = timestamp;
      }
    }
  }
  return json_obj;
}
void Response::updateTraceInManagedStore() {
  if (managedStore::GetManagedObjectStore()->getConfig().timetrace) {
    nlohmann::json json_obj = timetraceToJson();
    managedStore::GetManagedObjectStore()->storeTimeTrace(json_obj);
  }
}

}  // namespace crow
