#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/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(WARNING) << "Authorization failure at " << req.Target() << ": "
                 << status.error_message();
    resp.SetToForbidden();
    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
