#include "tlbmc/redfish/response.h"

#include <string_view>

#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "redfish_v1.pb.h"
#include "grpcpp/support/server_callback.h"
#include "grpcpp/support/status.h"
#include "nlohmann/json.hpp"

namespace milotic_tlbmc {

RedfishResponse::RedfishResponse(grpc::ServerUnaryReactor* reactor,
                                 redfish::v1::Response& grpc_response)
    : reactor_(reactor), grpc_response_(&grpc_response) {}

void RedfishResponse::End() {
  // Don't send response if end has already been called.
  if (end_called_) {
    return;
  }
  end_called_ = true;
  // If there is an async resp attached, then we will use it to send the
  // response back instead of the reactor.
  if (async_resp_ != nullptr) {
    for (const auto& element : http_response_.base()) {
      async_resp_->res.addHeader(element.name_string(), element.value());
    }
    async_resp_->res.result(http_response_.result());
    async_resp_->res.body() = http_response_.body();
    async_resp_->res.jsonValue = json_body_;
    return;
  }

  // If there is no grpc response, then we don't need to send the response.
  if (grpc_response_ == nullptr) {
    return;
  }

  auto* headers = grpc_response_->mutable_headers();
  for (const auto& element : http_response_.base()) {
    // Repeated headers are combined into a ',' separated list. See
    // https://www.rfc-editor.org/rfc/rfc9110.html#section-5.3-3.
    auto found = headers->find(element.name_string());
    if (found == headers->end()) {
      (*headers)[element.name_string()] = element.value();
    } else {
      found->second += ",";
      found->second += element.value();
    }
  }

  if (http_response_["OData-Version"] == "4.0") {
    *grpc_response_->mutable_json_str() = json_body_.dump(
        -1, ' ', true, nlohmann::json::error_handler_t::replace);
  } else {
    *grpc_response_->mutable_octet_stream() = http_response_.body();
  }
  grpc_response_->set_code(static_cast<unsigned int>(http_response_.result()));

  if (reactor_ != nullptr) {
    reactor_->Finish(grpc::Status::OK);
  }
}

void RedfishResponse::SetBodyToJson() {
  http_response_.base().erase("OData-Version");
  SetHeader("OData-Version", "4.0");
}

void RedfishResponse::SetBodyToOctetStream() {
  http_response_.base().erase("OData-Version");
}

void RedfishResponse::SetHeader(std::string_view key, std::string_view value) {
  http_response_.base().insert(key, value);
}

void RedfishResponse::SetBinaryBody(std::string_view body) {
  http_response_.body() = body;
}

void RedfishResponse::SetToNotFound(std::string_view error_message) {
  http_response_.result(boost::beast::http::status::not_found);

  nlohmann::json error_message_json;
  error_message_json["@odata.type"] = "#Message.v1_1_1.Message";
  error_message_json["MessageId"] = "Base.1.13.0.ResourceNotFound";
  error_message_json["Message"] = error_message;

  SetErrorMessage(error_message_json);
}

void RedfishResponse::SetToForbidden(std::string_view error_message) {
  http_response_.result(boost::beast::http::status::forbidden);

  nlohmann::json error_message_json;
  error_message_json["@odata.type"] = "#Message.v1_1_1.Message";
  error_message_json["MessageId"] = "Base.1.13.0.ResourceAtUriUnauthorized";
  error_message_json["Message"] = error_message;

  SetErrorMessage(error_message_json);
}

void RedfishResponse::SetToNotReady(std::string_view error_message) {
  http_response_.result(boost::beast::http::status::service_unavailable);

  nlohmann::json error_message_json;
  error_message_json["@odata.type"] = "#Message.v1_1_1.Message";
  error_message_json["MessageId"] = "Base.1.13.0.InternalError";
  error_message_json["Message"] = error_message;

  SetErrorMessage(error_message_json);
}

void RedfishResponse::SetToAbslStatus(const absl::Status& status) {
  switch (status.code()) {
    case absl::StatusCode::kNotFound:
      SetToNotFound(status.message());
      break;
    case absl::StatusCode::kPermissionDenied:
      SetToForbidden(status.message());
      break;
    case absl::StatusCode::kUnavailable:
      SetToNotReady(status.message());
      break;
    default:
      http_response_.result(boost::beast::http::status::internal_server_error);
      break;
  }
}

void RedfishResponse::SetErrorMessage(
    const nlohmann::json& error_message_json) {
  if (!json_body_.contains("/error")) {
    SetKeyInJsonBody(/*key=*/"/error/code", /*value=*/"Base.1.8.GeneralError");
    SetKeyInJsonBody(/*key=*/"/error/message",
                     /*value=*/
                     "A general error has occurred. See Resolution for "
                     "information on how to "
                     "resolve the error.");
  }

  AppendToKeyInJsonBody(/*key=*/"/error/@Message.ExtendedInfo",
                        /*value=*/error_message_json);
}

}  // namespace milotic_tlbmc
