#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/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
