#include "bmc/http_connection.h"

#include <cstddef>
#include <cstdint>
#include <string>
#include <utility>

#include "bmc/daemon_context_bmc.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"

// NOLINTBEGIN(readability/boost)
#include "boost/asio/ip/tcp.hpp"
#include "boost/beast/core.hpp"
#include "boost/beast/core/tcp_stream.hpp"
#include "boost/beast/http.hpp"
#include "boost/beast/version.hpp"
// NOLINTEND(readability/boost)

#include "nlohmann/json.hpp"
#include "nlohmann/json_fwd.hpp"

namespace safepower_agent {

namespace beast = boost::beast;
namespace http = beast::http;

using boost::beast::flat_buffer;
using boost::beast::tcp_stream;

HttpConnection::HttpConnection(absl::Duration connection_timeout,
                               absl::Duration write_timeout)
    : stream_(
          boost::asio::make_strand(DaemonContextBMC::Get().get_io_context())),
      connection_timeout_(connection_timeout),
      write_timeout_(write_timeout) {}

// perform_connection = connect -> write -> read -> callback
// all failing cases, skip to user provided callback with error
void HttpConnection::PerformConnection(
    http::verb verb, absl::string_view target,
    absl::AnyInvocable<void(absl::StatusOr<nlohmann::json>) &&> in_callback,
    const nlohmann::json& body, const absl::string_view ip,
    const uint16_t port) {
  verb_ = verb;
  body_ = body.dump();
  target_ = target;
  provided_callback_ = std::move(in_callback);

  boost::system::error_code ec;
  boost::asio::ip::address address =
      boost::asio::ip::address::from_string(std::string(ip).c_str(), ec);
  if (ec) {
    LOG(INFO) << "Unable to build address from string ip:" << ip;
  }
  end_point_.address(address);
  end_point_.port(port);
  stream_.expires_after(absl::ToChronoMilliseconds(connection_timeout_));
  VLOG(2) << absl::StrFormat( "Connecting to endpoint : %s:%d %s %s",
                         ip, port, target, body_);

  auto self = shared_from_this();
  stream_.async_connect(end_point_,
                        [self](beast::error_code ec) { self->Write(ec); });
}

void HttpConnection::Write(beast::error_code ec) {
  if (ec) {
    std::move(provided_callback_)(absl::UnavailableError(
        absl::StrCat("Failed to connect to BMC: ", ec.message())));
    return;
  }
  req_.method(verb_);
  req_.target(target_);
  req_.version(11); /*http version 1.1*/
  req_.set(http::field::host, "localhost");
  req_.set(http::field::content_type, "application/json");
  // string value must outlive the async write
  req_.body() = body_;
  VLOG(3) << absl::StrCat("http request body: ", req_.body());;
  req_.prepare_payload();
  stream_.expires_after(absl::ToChronoMilliseconds(write_timeout_));
  auto self = shared_from_this();
  http::async_write(stream_, req_, [self](beast::error_code ec, size_t t) {
    self->Read(ec, t);
  });
}

void HttpConnection::Read(beast::error_code ec, size_t) {
  if (ec) {
    std::move(provided_callback_)(absl::UnavailableError(
        absl::StrCat("Failed in http write:", ec.message())));
    return;
  }
  auto self = shared_from_this();
  http::async_read(
      stream_, buffer_, res_,
      [self](beast::error_code ec, size_t t) { self->Callback(ec, t); });
}

void HttpConnection::Callback(beast::error_code ec, std::size_t) {
  absl::Status status = absl::OkStatus();
  if (ec) {
    LOG(ERROR) << "callback error handler: " << ec.message();
    status = absl::UnknownError(
        absl::StrCat("Callback error handler: ", ec.message()));
    std::move(provided_callback_)(status);
    return;
  }
  VLOG(3) << absl::StrCat("http response body: ", res_.body());

  if (res_.result() != http::status::ok) {
    LOG(ERROR) << "bad http code " << res_.result();
    status = absl::UnavailableError(
        absl::StrCat("HTTP request failed with status: ", res_.result()));
    std::move(provided_callback_)(status);
    return;
  }
  nlohmann::json js_body = nlohmann::json::parse(res_.body(), /* cb */ nullptr,
  /* allow_exceptions */ false);
  if (js_body.is_discarded()) {
    status = absl::InvalidArgumentError(
        absl::StrCat("Failed to parse JSON from BMC: ", res_.body()));
    LOG(ERROR) << "response json " << res_.body();
    std::move(provided_callback_)(status);
    return;
  }
  std::move(provided_callback_)(js_body);
}
}  // namespace safepower_agent
