#include "tlbmc/redfish/expand_query_aggregator.h"

#include <algorithm>
#include <array>
#include <cstddef>
#include <limits>
#include <memory>
#include <string>
#include <system_error>
#include <utility>
#include <vector>

#include "absl/log/log.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "boost/url/url.hpp"  // NOLINT
#include "nlohmann/json_fwd.hpp"
#include "tlbmc/redfish/query_parameters.h"
#include "dbus_utility.hpp" // NOLINT
#include "async_resp.hpp" // NOLINT
#include "http_request.hpp" // NOLINT

namespace milotic_tlbmc {

using ::crow::Request;
using ::crow::Response;

std::string ExpandQueryAggregator::CreateExpandQueryUrl(
    absl::string_view url, [[maybe_unused]] const ExpandNode& expand_node) {
  return absl::Substitute(
      "$0?$$expand=$1($$levels=$2)", url,
      ExpandTypeToUrlParam(query_parameters_.GetExpandType()),
      std::to_string(query_parameters_.GetExpandLevel() - 1));
}

void ExpandQueryAggregator::StartQuery() {
  std::vector<ExpandNode> urls_to_expand = GetUnexpandedUrls(
      final_async_resp_->res.jsonValue, query_parameters_.GetExpandType());
  for (const ExpandNode& url_to_expand : urls_to_expand) {
    boost::urls::url expand_url(url_to_expand.url);
    boost::beast::http::request<boost::beast::http::string_body> request;
    std::string request_url =
        CreateExpandQueryUrl(expand_url.encoded_path(), url_to_expand);
    request.target(request_url);
    request.method(boost::beast::http::verb::get);

    std::error_code ec;
    Request sub_req(std::move(request), ec);
    auto sub_async_resp =
        std::make_shared<bmcweb::AsyncResp>(final_async_resp_->strand_);
    sub_async_resp->res.setCompleteRequestHandler(
        // We must extend the lifetime of the final_response to the lifetime
        // of the sub_async_resp.
        [expand_aggregator = shared_from_this(), url_to_expand](Response& res) {
          expand_aggregator->AddResponseToFinalResponse(
              url_to_expand.json_pointer, res);
        });
    LOG(INFO) << "Sub request: " << sub_req.target();
    smart_router_->Handle(sub_req, sub_async_resp);
  }
}

void ExpandQueryAggregator::AddResponseToFinalResponse(
    const nlohmann::json::json_pointer& location, Response& sub_response) {
  PropogateErrorCodeIfNeeded(location, sub_response);
  if (!sub_response.jsonValue.is_object() || sub_response.jsonValue.empty()) {
    return;
  }

  final_async_resp_->res.jsonValue[location] =
      std::move(sub_response.jsonValue);
}

// Make error codes distinct between the query made.
void ExpandQueryAggregator::PropogateErrorCodeIfNeeded(
    const nlohmann::json::json_pointer& location, Response& sub_response) {
  if (sub_response.resultInt() >= 200 && sub_response.resultInt() < 400) {
    return;
  }

  final_async_resp_->res.result(
      DetermineFinalErrorCode(sub_response.resultInt()));

  if (sub_response.jsonValue.contains("error")) {
    if (!final_async_resp_->res.jsonValue.contains("error")) {
      final_async_resp_->res.jsonValue["error"] = nlohmann::json::object();
    }
    final_async_resp_->res.jsonValue["error"][location] =
        std::move(sub_response.jsonValue["error"]);
    sub_response.jsonValue.clear();
  }
}

// Propogates the worst error code to the final response.
// The order of error code is (from high to low)
// 500 Internal Server Error
// 511 Network Authentication Required
// 510 Not Extended
// 508 Loop Detected
// 507 Insufficient Storage
// 506 Variant Also Negotiates
// 505 HTTP Version Not Supported
// 504 Gateway Timeout
// 503 Service Unavailable
// 502 Bad Gateway
// 501 Not Implemented
// 401 Unauthorized
// 451 - 409 Error codes (not listed explictly)
// 408 Request Timeout
// 407 Proxy Authentication Required
// 406 Not Acceptable
// 405 Method Not Allowed
// 404 Not Found
// 403 Forbidden
// 402 Payment Required
// 400 Bad Request
unsigned ExpandQueryAggregator::DetermineFinalErrorCode(
    unsigned sub_response_code) {
  unsigned cur_code = final_async_resp_->res.resultInt();
  // We keep a explicit list for error codes that this project often uses
  // Higer priority codes are in lower indexes
  constexpr std::array<unsigned, 13> ordered_codes = {
      500, 507, 503, 502, 501, 401, 412, 409, 406, 405, 404, 403, 400};
  size_t final_code_index = std::numeric_limits<size_t>::max();
  size_t sub_response_code_index = std::numeric_limits<size_t>::max();
  for (size_t i = 0; i < ordered_codes.size(); ++i) {
    if (ordered_codes[i] == cur_code) {
      final_code_index = i;
    }
    if (ordered_codes[i] == sub_response_code) {
      sub_response_code_index = i;
    }
  }
  if (final_code_index != std::numeric_limits<size_t>::max() &&
      sub_response_code_index != std::numeric_limits<size_t>::max()) {
    return final_code_index <= sub_response_code_index ? cur_code
                                                       : sub_response_code;
  }
  if (sub_response_code == 500 || cur_code == 500) {
    return 500;
  }
  if (sub_response_code > 500 || cur_code > 500) {
    return std::max(cur_code, sub_response_code);
  }
  if (sub_response_code == 401) {
    return sub_response_code;
  }
  return std::max(cur_code, sub_response_code);
}

}  // namespace milotic_tlbmc
