#include "tlbmc/redfish/query.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/time/clock.h"
#include "boost/beast/http/string_body.hpp"  //NOLINT
#include "boost/beast/http/verb.hpp"  //NOLINT`
#include "boost/url/url.hpp"  // NOLINT
#include "redfish_v1.pb.h"
#include "grpcpp/support/status.h"
#include "tlbmc/redfish/expand_query_aggregator.h"
#include "tlbmc/redfish/query_parameters.h"
#include "tlbmc/redfish/request.h"
#include "tlbmc/redfish/response.h"
#include "tlbmc/redfish/routing.h"
#include "tlbmc/trace/tracer.h"
#include "bmcweb_authorizer_singleton.h"
#include "router_interface.h"

namespace milotic_tlbmc {

using ::crow::RouterInterface;
using ::milotic::authz::BmcWebAuthorizerSingleton;

bool RedfishPreprocess(const RedfishRequest& req, RedfishResponse& resp) {
  milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint("Tlbmc-Authz-Begin",
                                                            absl::Now());
  // Most Redfish responses are JSON, so we can set the content type here.
  resp.SetBodyToJson();

  // No authorization.
  if (!req.FromGrpc()) {
    milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint("Tlbmc-Authz-End",
                                                              absl::Now());
    return true;
  }
  BmcWebAuthorizerSingleton::RequestState request_state;
  request_state.with_trust_bundle = req.WithTrustBundle();
  request_state.peer_authenticated = req.PeerAuthenticated();
  request_state.peer_privileges = req.PeerPrivileges();

  grpc::Status status = BmcWebAuthorizerSingleton::GetInstance().Authorize(
      req.Target(), req.Method(), request_state);
  if (!status.ok()) {
    // Log both for server side and client side.
    std::string error_message =
        absl::StrFormat("Authorization failure at %s: %s", req.Target(),
                        status.error_message());
    LOG(WARNING) << error_message;
    resp.SetToForbidden(error_message);
    resp.End();
    milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint("Tlbmc-Authz-End",
                                                              absl::Now());
    return false;
  }
  milotic_tlbmc::Tracer::GetInstance().AddRepeatedDatapoint("Tlbmc-Authz-End",
                                                            absl::Now());
  return true;
}

namespace {

void SynchronousExpand(const crow::Router& tlbmc_router, RedfishResponse& resp,
                       const QueryParameters& query_parameters) {
  // For each expand level we do the following:
  // 1. Get all unexpanded Redfish URLs in the response
  // 2. Query the Redfish URLs.
  // 3. Replace the Redfish URLs in the response with the expanded URLs.
  for (int i = 0; i < query_parameters.GetExpandLevel(); ++i) {
    std::vector<ExpandNode> urls_to_expand =
        GetUnexpandedUrls(resp.GetJsonBody(), 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;
      request.target(expand_url.encoded_path());
      request.method(boost::beast::http::verb::get);

      RedfishRequest sub_req(std::move(request));
      // Have to create a redfish response since you cannot create a tlbmc
      // response without one.
      RedfishResponse sub_resp;

      tlbmc_router.Handle(sub_req, sub_resp);

      resp.SetKeyInJsonBody(url_to_expand.json_pointer, sub_resp.GetJsonBody());
    }
  }
}

void AsynchronousExpand(RouterInterface* smart_router, RedfishResponse& resp,
                        const QueryParameters& query_parameters) {
  // We need to end the response before we can send it to the aggregator.
  // This sends the current response to the async resp, and then starts the
  // aggregator.
  resp.End();
  auto expand_query_aggregator = std::make_shared<ExpandQueryAggregator>(
      resp.ReleaseAsyncResp(), smart_router, query_parameters);
  LOG(INFO) << "Starting expand query aggregator";
  expand_query_aggregator->StartQuery();
}

void HandleExpandQueryParameter(RouterInterface* smart_router,
                                const crow::Router& tlbmc_router,
                                const RedfishRequest& req,
                                RedfishResponse& resp) {
  QueryParameters query_parameters = req.GetQueryParameters();
  if (query_parameters.GetExpandType() == ExpandType::kNone ||
      query_parameters.GetExpandLevel() == 0) {
    return;
  }

  LOG(INFO) << "HandleExpandQueryParameter: " << req.Target();

  // tlbmc only requests are guaranteed to be synchronous, therefore we can
  // perform synchronous expand.
  if (req.TlbmcOnly()) {
    SynchronousExpand(tlbmc_router, resp, query_parameters);
    return;
  }

  // If smart router is nullptr, then return internal error.
  if (smart_router == nullptr) {
    resp.SetToAbslStatus(absl::InternalError("Smart router is nullptr"));
    LOG(WARNING) << "Smart router is nullptr, cannot perform asynchronous "
                    "expand for request: "
                 << req.Target();
    return;
  }

  // Otherwise, we need to perform asynchronous expand.
  AsynchronousExpand(smart_router, resp, query_parameters);
}

}  // namespace

void RedfishPostprocess(RouterInterface* smart_router,
                        const crow::Router& tlbmc_router,
                        const RedfishRequest& req, RedfishResponse& resp) {
  // Currently only supports expand query parameter.
  HandleExpandQueryParameter(smart_router, tlbmc_router, req, resp);
}

}  // namespace milotic_tlbmc
