#ifndef THIRD_PARTY_GBMCWEB_HTTP_HTTP_CLIENT_H_
#define THIRD_PARTY_GBMCWEB_HTTP_HTTP_CLIENT_H_

/*
// Copyright (c) 2020 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/

#include <openssl/err.h>
#include <openssl/ssl.h>  // NOLINT

#include <chrono>  // NOLINT
#include <cstdint>
#include <cstdlib>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>

#include "boost/asio/connect.hpp"  // NOLINT
#include "boost/asio/io_context.hpp"  // NOLINT
#include "boost/asio/ip/address.hpp"  // NOLINT
#include "boost/asio/ip/basic_endpoint.hpp"  // NOLINT
#include "boost/asio/ip/tcp.hpp"  // NOLINT
#include "boost/asio/ssl/context.hpp"  // NOLINT
#include "boost/asio/ssl/error.hpp"  // NOLINT
#include "boost/asio/steady_timer.hpp"  // NOLINT
#include "boost/beast/core/flat_buffer.hpp"  // NOLINT
#include "boost/beast/core/flat_static_buffer.hpp"  // NOLINT
#include "boost/beast/http/message.hpp"  // NOLINT
#include "boost/beast/http/parser.hpp"  // NOLINT
#include "boost/beast/http/read.hpp"  // NOLINT
#include "boost/beast/http/string_body.hpp"  // NOLINT
#include "boost/beast/http/write.hpp"  // NOLINT
#include "boost/beast/ssl/ssl_stream.hpp"  // NOLINT
#include "boost/beast/version.hpp"  // NOLINT
#include "boost/container/devector.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "http_response.hpp"
#include "logging.hpp"
#include "async_resolve.hpp"
#include "ssl_key_handler.hpp"
#include "managed_store.hpp"

namespace crow {

// With Redfish Aggregation it is assumed we will connect to another instance
// of BMCWeb which can handle 100 simultaneous connections.
constexpr size_t maxPoolSize = 20;
constexpr size_t maxRequestQueueSize = 500;
constexpr unsigned int httpReadBodyLimit = 131072;
constexpr unsigned int httpReadBufferSize = 4096;

enum class ConnState : std::uint8_t {
  initialized,
  resolveInProgress,
  resolveFailed,
  connectInProgress,
  connectFailed,
  connected,
  handshakeInProgress,
  handshakeFailed,
  sendInProgress,
  sendFailed,
  recvInProgress,
  recvFailed,
  idle,
  closed,
  suspended,
  terminated,
  abortConnection,
  sslInitFailed,
  retry
};

static inline boost::system::error_code defaultRetryHandler(
    unsigned int respCode) {
  // As a default, assume 200X is alright
  BMCWEB_LOG_DEBUG << "Using default check for response code validity";
  if ((respCode < 200) || (respCode >= 300)) {
    return boost::system::errc::make_error_code(
        boost::system::errc::result_out_of_range);
  }

  // Return 0 if the response code is valid
  return boost::system::errc::make_error_code(boost::system::errc::success);
};

// We need to allow retry information to be set before a message has been sent
// and a connection pool has been created
struct ConnectionPolicy {
  uint32_t maxRetryAttempts = 5;  // NOLINT

  // the max size of requests in bytes.  0 for unlimited
  boost::optional<uint64_t> requestByteLimit = httpReadBodyLimit;  // NOLINT

  size_t maxConnections = 1;  // NOLINT

  std::string retryPolicyAction = "TerminateAfterRetries";  // NOLINT

  std::chrono::seconds retryIntervalSecs = std::chrono::seconds(0);  // NOLINT
  std::function<boost::system::error_code(unsigned int respCode)>
      invalidResp =  // NOLINT
      defaultRetryHandler;
};

struct PendingRequest {
  boost::beast::http::request<boost::beast::http::string_body> req;
  std::function<void(bool, uint32_t, Response&)> callback;
  PendingRequest(
      boost::beast::http::request<boost::beast::http::string_body>&& reqIn,
      const std::function<void(bool, uint32_t, Response&)>& callbackIn)
      : req(std::move(reqIn)), callback(callbackIn) {}
};

class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo> {
 private:
  ConnState state = ConnState::initialized;      // NOLINT
  uint32_t retryCount = 0;                       // NOLINT
  std::string subId;                             // NOLINT
  std::shared_ptr<ConnectionPolicy> connPolicy;  // NOLINT
  std::string host;                              // NOLINT
  uint16_t port;                                 // NOLINT
  uint32_t connId;                               // NOLINT

  // Data buffers
  boost::beast::http::request<boost::beast::http::string_body> req;  // NOLINT
  std::optional<
      boost::beast::http::response_parser<boost::beast::http::string_body>>
      parser;                                                   // NOLINT
  boost::beast::flat_static_buffer<httpReadBufferSize> buffer;  // NOLINT
  Response res;                                                 // NOLINT

  // Ascync callables
  std::function<void(bool, uint32_t, Response&)> callback;  // NOLINT
  crow::async_resolve::Resolver resolver;                   // NOLINT
  boost::asio::io_context& ioc;                             // NOLINT
  bool useSsl;                                              // NOLINT
  boost::asio::ip::tcp::socket conn;                        // NOLINT
  std::optional<boost::beast::ssl_stream<boost::asio::ip::tcp::socket&>>
      sslConn;  // NOLINT

  boost::asio::steady_timer timer;  // NOLINT

  // Increments whenever the pending asynchronous work changes: an operation
  // deadline or retry wait is armed, or an operation completes. Timer
  // handlers capture the value at arm time and discard themselves if it has
  // moved on, because cancel() cannot revoke a handler the reactor has
  // already queued with its expiry code.
  uint64_t timerGeneration = 0;  // NOLINT

  friend class ConnectionPool;

  // Arms the per-operation deadline for the next asynchronous operation.
  void armOperationTimeout() {
    timer.expires_after(std::chrono::seconds(30));
    timer.async_wait(
        std::bind_front(onTimeout, weak_from_this(), ++timerGeneration));
  }

  // Marks the pending operation as complete: invalidates any timeout or
  // retry handler that is already queued and cancels the timer proper.
  void completeOperation() {
    ++timerGeneration;
    timer.cancel();
  }

  void doResolve() {
    state = ConnState::resolveInProgress;
    BMCWEB_LOG_DEBUG << "Trying to resolve: " << host << ":"
                     << std::to_string(port)
                     << ", id: " << std::to_string(connId);

    resolver.asyncResolve(host, port,
                          std::bind_front(&ConnectionInfo::afterResolve, this,
                                          shared_from_this()));
  }

  void afterResolve(
      const std::shared_ptr<ConnectionInfo>& /*self*/,
      const boost::beast::error_code ec,
      const std::vector<boost::asio::ip::tcp::endpoint>& endpointList) {
    if (ec || (endpointList.empty())) {
      BMCWEB_LOG_ERROR << "Resolve failed: " << ec.message();
      state = ConnState::resolveFailed;
      waitAndRetry();
      return;
    }
    BMCWEB_LOG_DEBUG << "Resolved " << host << ":" << std::to_string(port)
                     << ", id: " << std::to_string(connId);
    state = ConnState::connectInProgress;

    BMCWEB_LOG_DEBUG << "Trying to connect to: " << host << ":"
                     << std::to_string(port)
                     << ", id: " << std::to_string(connId);

    armOperationTimeout();

    boost::asio::async_connect(conn, endpointList,
                               std::bind_front(&ConnectionInfo::afterConnect,
                                               this, shared_from_this()));
  }

  void afterConnect(const std::shared_ptr<ConnectionInfo>& /*self*/,
                    boost::beast::error_code ec,
                    const boost::asio::ip::tcp::endpoint& endpoint) {
    // The operation already timed out.  We don't want do continue down
    // this branch
    if (ec && ec == boost::asio::error::operation_aborted) {
      return;
    }

    completeOperation();
    if (ec) {
      BMCWEB_LOG_ERROR << "Connect " << endpoint.address().to_string() << ":"
                       << std::to_string(endpoint.port())
                       << ", id: " << std::to_string(connId)
                       << " failed: " << ec.message();
      state = ConnState::connectFailed;
      waitAndRetry();
      return;
    }
    BMCWEB_LOG_DEBUG << "Connected to: " << endpoint.address().to_string()
                     << ":" << std::to_string(endpoint.port())
                     << ", id: " << std::to_string(connId);
    if (sslConn) {
      doSslHandshake();
      return;
    }
    state = ConnState::connected;
    sendMessage();
  }

  void doSslHandshake() {
    if (!sslConn) {
      return;
    }
    state = ConnState::handshakeInProgress;
    armOperationTimeout();
    sslConn->async_handshake(boost::asio::ssl::stream_base::client,
                             std::bind_front(&ConnectionInfo::afterSslHandshake,
                                             this, shared_from_this()));
  }

  void afterSslHandshake(const std::shared_ptr<ConnectionInfo>& /*self*/,
                         boost::beast::error_code ec) {
    // The operation already timed out.  We don't want do continue down
    // this branch
    if (ec && ec == boost::asio::error::operation_aborted) {
      return;
    }

    completeOperation();
    if (ec) {
      BMCWEB_LOG_ERROR << "SSL Handshake failed -"
                       << " id: " << std::to_string(connId)
                       << " error: " << ec.message();
      state = ConnState::handshakeFailed;
      waitAndRetry();
      return;
    }
    BMCWEB_LOG_DEBUG << "SSL Handshake successful -"
                     << " id: " << std::to_string(connId);
    state = ConnState::connected;
    sendMessage();
  }

  void sendMessage() {
    state = ConnState::sendInProgress;

    // Set a timeout on the operation
    armOperationTimeout();

    // Send the HTTP request to the remote host
    if (sslConn) {
      boost::beast::http::async_write(
          *sslConn, req,
          std::bind_front(&ConnectionInfo::afterWrite, this,
                          shared_from_this()));
    } else {
      boost::beast::http::async_write(
          conn, req,
          std::bind_front(&ConnectionInfo::afterWrite, this,
                          shared_from_this()));
    }
  }

  void afterWrite(const std::shared_ptr<ConnectionInfo>& /*self*/,
                  const boost::beast::error_code& ec, size_t bytesTransferred) {
    // The operation already timed out.  We don't want do continue down
    // this branch
    if (ec && ec == boost::asio::error::operation_aborted) {
      return;
    }

    completeOperation();
    if (ec) {
      BMCWEB_LOG_ERROR << "sendMessage() failed: " << ec.message();
      state = ConnState::sendFailed;
      waitAndRetry();
      return;
    }
    BMCWEB_LOG_DEBUG << "sendMessage() bytes transferred: " << bytesTransferred;

    recvMessage();
  }

  void recvMessage() {
    state = ConnState::recvInProgress;

    parser.emplace(std::piecewise_construct, std::make_tuple());

    parser->body_limit(connPolicy->requestByteLimit);

    armOperationTimeout();

    // Receive the HTTP response
    if (sslConn) {
      boost::beast::http::async_read(*sslConn, buffer, *parser,
                                     std::bind_front(&ConnectionInfo::afterRead,
                                                     this, shared_from_this()));
    } else {
      boost::beast::http::async_read(conn, buffer, *parser,
                                     std::bind_front(&ConnectionInfo::afterRead,
                                                     this, shared_from_this()));
    }
  }

  void afterRead(const std::shared_ptr<ConnectionInfo>& /*self*/,
                 const boost::beast::error_code& ec,
                 const std::size_t& bytesTransferred) {
    // The operation already timed out.  We don't want do continue down
    // this branch
    if (ec && ec == boost::asio::error::operation_aborted) {
      return;
    }

    completeOperation();
    if (ec && ec != boost::asio::ssl::error::stream_truncated) {
      BMCWEB_LOG_ERROR << "recvMessage() failed: " << ec.message();
      state = ConnState::recvFailed;
      waitAndRetry();
      return;
    }
    BMCWEB_LOG_DEBUG << "recvMessage() bytes transferred: " << bytesTransferred;
    BMCWEB_LOG_DEBUG << "recvMessage() data: " << parser->get().body();

    unsigned int resp_code = parser->get().result_int();
    BMCWEB_LOG_DEBUG << "recvMessage() Header Response Code: " << resp_code;

    // Make sure the received response code is valid as defined by
    // the associated retry policy
    if (connPolicy->invalidResp(resp_code)) {
      // The listener failed to receive the Sent-Event
      BMCWEB_LOG_ERROR << "recvMessage() Listener Failed to "
                          "receive Sent-Event. Header Response Code: "
                       << resp_code;
      state = ConnState::recvFailed;
      waitAndRetry();
      return;
    }

    // Send is successful
    // Reset the counter just in case this was after retrying
    retryCount = 0;

    // Keep the connection alive if server supports it
    // Else close the connection
    BMCWEB_LOG_DEBUG << "recvMessage() keepalive : " << parser->keep_alive();

    // Copy the response into a Response object so that it can be
    // processed by the callback function.
    res.stringResponse = parser->release();
    if (callback) {
      callback(parser->keep_alive(), connId, res);
    } else {
      // Unreachable while the generation checks hold; if this fires, a
      // stale completion survived them and the response has no owner.
      BMCWEB_LOG_CRITICAL << "Response completed but callback was empty, id: "
                          << std::to_string(connId);
    }
    res.clear();
  }

  static void onTimeout(const std::weak_ptr<ConnectionInfo>& weakSelf,
                        uint64_t generation,
                        const boost::system::error_code& ec) {
    if (ec == boost::asio::error::operation_aborted) {
      BMCWEB_LOG_DEBUG << "async_wait failed since the operation is aborted";
      return;
    }
    if (ec) {
      BMCWEB_LOG_ERROR << "async_wait failed: " << ec.message();
      // If the timer fails, we need to close the socket anyway, same as
      // if it expired.
    }
    std::shared_ptr<ConnectionInfo> self = weakSelf.lock();
    if (self == nullptr) {
      return;
    }
    if (generation != self->timerGeneration) {
      // The operation completed while this expiry was already queued;
      // cancel() cannot revoke a queued handler, so it discards itself.
      BMCWEB_LOG_DEBUG << "Ignoring stale operation timeout";
      return;
    }
    self->waitAndRetry();
  }

  void waitAndRetry() {
    // Stop the in-flight operation before deciding this connection's fate.
    // A completion the reactor has already queued still runs; the
    // generation checks in the timer handlers neutralize that case.
    boost::system::error_code cancelEc;
    conn.cancel(cancelEc);
    if ((retryCount >= connPolicy->maxRetryAttempts) ||
        (state == ConnState::sslInitFailed)) {
      BMCWEB_LOG_ERROR << "Maximum number of retries reached.";
      BMCWEB_LOG_DEBUG << "Retry policy: " << connPolicy->retryPolicyAction;

      if (connPolicy->retryPolicyAction == "TerminateAfterRetries") {
        // TODO: delete subscription
        state = ConnState::terminated;
      }
      if (connPolicy->retryPolicyAction == "SuspendRetries") {
        state = ConnState::suspended;
      }

      // We want to return a 502 to indicate there was an error with
      // the external server
      res.result(boost::beast::http::status::bad_gateway);
      if (callback) {
        callback(false, connId, res);
      } else {
        // Expected only when SSL init fails during construction, before a
        // request was ever assigned to this connection.
        BMCWEB_LOG_ERROR << "Connection terminated with no pending callback,"
                         << " id: " << std::to_string(connId);
      }
      res.clear();

      // Reset the retrycount to zero so that client can try connecting
      // again if needed
      retryCount = 0;
      return;
    }

    retryCount++;

    BMCWEB_LOG_DEBUG << "Attempt retry after "
                     << std::to_string(connPolicy->retryIntervalSecs.count())
                     << " seconds. RetryCount = " << retryCount;
    timer.expires_after(connPolicy->retryIntervalSecs);
    timer.async_wait(std::bind_front(&ConnectionInfo::onTimerDone, this,
                                     shared_from_this(), ++timerGeneration));
  }

  void onTimerDone(const std::shared_ptr<ConnectionInfo>& /*self*/,
                   uint64_t generation, const boost::system::error_code& ec) {
    if (ec == boost::asio::error::operation_aborted) {
      BMCWEB_LOG_DEBUG << "Retry wait was cancelled";
      return;
    }
    if (ec) {
      BMCWEB_LOG_ERROR << "async_wait failed: " << ec.message();
      // A timer error still warrants the retry the policy asked for.
    }
    if (generation != timerGeneration) {
      // The response arrived and was delivered while this retry was
      // pending; there is nothing left to retry.
      BMCWEB_LOG_DEBUG << "Ignoring stale retry wait";
      return;
    }

    // Close the connection and restart from resolve on a fresh transport.
    // The peer is unresponsive or broken, so skip the graceful SSL
    // shutdown; its completion may never arrive and would stall the retry.
    shutdownConn(true);
  }

  void shutdownConn(bool retry) {
    boost::beast::error_code ec;
    // NOLINTNEXTLINE(bugprone-unused-return-value)
    conn.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
    conn.close();

    // not_connected happens sometimes so don't bother reporting it.
    if (ec && ec != boost::beast::errc::not_connected) {
      BMCWEB_LOG_ERROR << host << ":" << std::to_string(port)
                       << ", id: " << std::to_string(connId)
                       << " shutdown failed: " << ec.message();
    } else {
      BMCWEB_LOG_DEBUG << host << ":" << std::to_string(port)
                       << ", id: " << std::to_string(connId)
                       << " closed gracefully";
    }

    if (retry) {
      // Now let's try to resend the data
      state = ConnState::retry;
      restartConnection();
    } else {
      state = ConnState::closed;
    }
  }

  void doClose(bool retry = false) {
    if (!sslConn) {
      shutdownConn(retry);
      return;
    }

    sslConn->async_shutdown(std::bind_front(&ConnectionInfo::afterSslShutdown,
                                            this, shared_from_this(), retry));
  }

  void afterSslShutdown(const std::shared_ptr<ConnectionInfo>& /*self*/,
                        bool retry, const boost::system::error_code& ec) {
    if (ec) {
      BMCWEB_LOG_ERROR << host << ":" << std::to_string(port)
                       << ", id: " << std::to_string(connId)
                       << " shutdown failed: " << ec.message();
    } else {
      BMCWEB_LOG_DEBUG << host << ":" << std::to_string(port)
                       << ", id: " << std::to_string(connId)
                       << " closed gracefully";
    }
    shutdownConn(retry);
  }

  bool setCipherSuiteTLSext() {
    if (!sslConn) {
      return false;
    }

#ifdef GOOGLE3_GBMCWEB_BUILD
    if (SSL_set_tlsext_host_name(sslConn->native_handle(), host.c_str()) == 0)
#else
    // NOTE: The SSL_set_tlsext_host_name is defined in tlsv1.h header
    // file but its having old style casting (name is cast to void*).
    // Since bmcweb compiler treats all old-style-cast as error, its
    // causing the build failure. So replaced the same macro inline and
    // did corrected the code by doing static_cast to viod*. This has to
    // be fixed in openssl library in long run. Set SNI Hostname (many
    // hosts need this to handshake successfully)
    if (SSL_ctrl(sslConn->native_handle(), SSL_CTRL_SET_TLSEXT_HOSTNAME,
                 TLSEXT_NAMETYPE_host_name,
                 static_cast<void*>(&host.front())) == 0)
#endif
    {
      boost::beast::error_code ec{static_cast<int>(::ERR_get_error()),
                                  boost::asio::error::get_ssl_category()};

      BMCWEB_LOG_ERROR << "SSL_set_tlsext_host_name " << host << ":" << port
                       << ", id: " << std::to_string(connId)
                       << " failed: " << ec.message();
      // Set state as sslInit failed so that we close the connection
      // and take appropriate action as per retry configuration.
      state = ConnState::sslInitFailed;
      waitAndRetry();
      return false;
    }
    return true;
  }

  bool initializeSslConn() {
    std::optional<boost::asio::ssl::context> ssl_ctx =
        ensuressl::getSSLClientContext();

    if (!ssl_ctx) {
      BMCWEB_LOG_ERROR << "prepareSSLContext failed - " << host << ":" << port
                       << ", id: " << std::to_string(connId);
      // Don't retry if failure occurs while preparing SSL context
      // such as certificate is invalid or set cipher failure or set
      // host name failure etc... Setting conn state to sslInitFailed
      // and connection state will be transitioned to next state
      // depending on retry policy set by subscription.
      state = ConnState::sslInitFailed;
      waitAndRetry();
      return false;
    }
    sslConn.emplace(conn, *ssl_ctx);
    return setCipherSuiteTLSext();
  }

  // Retries and reconnects must not reuse the old transport: the socket has
  // been shut down, and an SSL session that already ran a handshake cannot
  // run another one. Recreate both, then resolve again.
  void restartConnection() {
    sslConn.reset();
    conn = boost::asio::ip::tcp::socket(ioc);
    if (useSsl) {
      if (!initializeSslConn()) {
        return;
      }
    }
    doResolve();
  }

 public:
  explicit ConnectionInfo(boost::asio::io_context& iocIn,
                          const std::string& idIn,
                          const std::shared_ptr<ConnectionPolicy>& connPolicyIn,
                          const std::string& destIPIn, uint16_t destPortIn,
                          bool useSSL, unsigned int connIdIn)
      : subId(idIn),
        connPolicy(connPolicyIn),
        host(destIPIn),
        port(destPortIn),
        connId(connIdIn),
        ioc(iocIn),
        useSsl(useSSL),
        conn(iocIn),
        timer(iocIn) {
    if (useSsl) {
      initializeSslConn();
    }
  }
};

class ConnectionPool : public std::enable_shared_from_this<ConnectionPool> {
 private:
  boost::asio::io_context& ioc;                              // NOLINT
  std::string id;                                            // NOLINT
  std::shared_ptr<ConnectionPolicy> connPolicy;              // NOLINT
  std::string destIP;                                        // NOLINT
  uint16_t destPort;                                         // NOLINT
  bool useSSL;                                               // NOLINT
  std::vector<std::shared_ptr<ConnectionInfo>> connections;  // NOLINT
  boost::container::devector<PendingRequest> requestQueue;   // NOLINT

  friend class HttpClient;

  // Configure a connections's request, callback, and retry info in
  // preparation to begin sending the request
  void setConnProps(ConnectionInfo& conn) {
    if (requestQueue.empty()) {
      BMCWEB_LOG_ERROR << "setConnProps() should not have been called when "
                          "requestQueue is empty";
      return;
    }

    auto next_req = requestQueue.front();
    conn.req = std::move(next_req.req);
    conn.callback = std::move(next_req.callback);

    BMCWEB_LOG_DEBUG << "Setting properties for connection " << conn.host << ":"
                     << std::to_string(conn.port)
                     << ", id: " << std::to_string(conn.connId);

    // We can remove the request from the queue at this point
    requestQueue.pop_front();
  }

  // Gets called as part of callback after request is sent
  // Reuses the connection if there are any requests waiting to be sent
  // Otherwise closes the connection if it is not a keep-alive
  void sendNext(bool keepAlive, uint32_t connId) {
    auto conn = connections[connId];

    // Allow the connection's handler to be deleted
    // This is needed because of Redfish Aggregation passing an
    // AsyncResponse shared_ptr to this callback
    conn->callback = nullptr;

    // Reuse the connection to send the next request in the queue
    if (!requestQueue.empty()) {
      BMCWEB_LOG_DEBUG << std::to_string(requestQueue.size())
                       << " requests remaining in queue for " << destIP << ":"
                       << std::to_string(destPort) << ", reusing connnection "
                       << std::to_string(connId);

      setConnProps(*conn);

      if (keepAlive) {
        conn->sendMessage();
      } else {
        // Server is not keep-alive enabled so we need to close the
        // connection and then start over from resolve. doClose(true)
        // restarts on a fresh transport once the shutdown completes,
        // instead of racing a resolve against an asynchronous SSL
        // shutdown on the same socket.
        conn->doClose(true);
      }
      return;
    }

    // No more messages to send so close the connection if necessary
    if (keepAlive) {
      conn->state = ConnState::idle;
    } else {
      // Abort the connection since server is not keep-alive enabled
      conn->state = ConnState::abortConnection;
      conn->doClose();
    }
  }

  void sendData(std::string& data, const std::string& destUri,
                const boost::beast::http::fields& httpHeader,
                const boost::beast::http::verb verb,
                const std::function<void(Response&)>& resHandler) {
    // Construct the request to be sent
    boost::beast::http::request<boost::beast::http::string_body> this_req(
        verb, destUri, 11, "", httpHeader);
    this_req.set(boost::beast::http::field::host, destIP);
    this_req.keep_alive(true);
    this_req.body() = std::move(data);
    this_req.prepare_payload();
    auto cb = std::bind_front(&ConnectionPool::afterSendData, weak_from_this(),
                              resHandler);
    // Reuse an existing connection if one is available
    for (unsigned int i = 0; i < connections.size(); i++) {
      auto conn = connections[i];
      if ((conn->state == ConnState::idle) ||
          (conn->state == ConnState::initialized) ||
          (conn->state == ConnState::closed)) {
        conn->req = std::move(this_req);
        conn->callback = std::move(cb);
        std::string common_msg = std::to_string(i) + " from pool " + destIP +
                                 ":" + std::to_string(destPort);

        if (conn->state == ConnState::idle) {
          BMCWEB_LOG_DEBUG << "Grabbing idle connection " << common_msg;
          conn->sendMessage();
        } else {
          BMCWEB_LOG_DEBUG << "Reusing existing connection " << common_msg;
          conn->restartConnection();
        }
        return;
      }
    }

    // All connections in use so create a new connection or add request to
    // the queue
    if (connections.size() < connPolicy->maxConnections) {
      BMCWEB_LOG_DEBUG << "Adding new connection to pool " << destIP << ":"
                       << std::to_string(destPort);
      auto conn = addConnection();
      conn->req = std::move(this_req);
      conn->callback = std::move(cb);
      conn->doResolve();
    } else if (requestQueue.size() < maxRequestQueueSize) {
      BMCWEB_LOG_ERROR << "Max pool size reached. Adding data to queue.";
      requestQueue.emplace_back(std::move(this_req), std::move(cb));
    } else {
      // If we can't buffer the request then we should let the callback
      // handle a 429 Too Many Requests dummy response
      BMCWEB_LOG_ERROR << destIP << ":" << std::to_string(destPort)
                       << " request queue full.  Dropping request.";
      Response dummy_res;
      dummy_res.result(boost::beast::http::status::too_many_requests);
      resHandler(dummy_res);
    }
  }

  // Callback to be called once the request has been sent
  static void afterSendData(const std::weak_ptr<ConnectionPool>& weakSelf,
                            const std::function<void(Response&)>& resHandler,
                            bool keepAlive, uint32_t connId, Response& res) {
    // Allow provided callback to perform additional processing of the
    // request
    resHandler(res);

    // If requests remain in the queue then we want to reuse this
    // connection to send the next request
    std::shared_ptr<ConnectionPool> self = weakSelf.lock();
    if (!self) {
      BMCWEB_LOG_CRITICAL << self << " Failed to capture connection";
      return;
    }

    self->sendNext(keepAlive, connId);
  }

  std::shared_ptr<ConnectionInfo>& addConnection() {
    unsigned int new_id = static_cast<unsigned int>(connections.size());

    auto& ret = connections.emplace_back(std::make_shared<ConnectionInfo>(
        ioc, id, connPolicy, destIP, destPort, useSSL, new_id));

    BMCWEB_LOG_DEBUG << "Added connection "
                     << std::to_string(connections.size() - 1) << " to pool "
                     << destIP << ":" << std::to_string(destPort);

    return ret;
  }

 public:
  explicit ConnectionPool(boost::asio::io_context& iocIn,
                          const std::string& idIn,
                          const std::shared_ptr<ConnectionPolicy>& connPolicyIn,
                          const std::string& destIPIn, uint16_t destPortIn,
                          bool useSSLIn)
      : ioc(iocIn),
        id(idIn),
        connPolicy(connPolicyIn),
        destIP(destIPIn),
        destPort(destPortIn),
        useSSL(useSSLIn) {
    BMCWEB_LOG_DEBUG << "Initializing connection pool for " << destIP << ":"
                     << std::to_string(destPort);

    // Initialize the pool with a single connection
    addConnection();
  }
};

class HttpClient {
 private:
  std::unordered_map<std::string, std::shared_ptr<ConnectionPool>>
      connectionPools;            // NOLINT
  boost::asio::io_context& ioc =  // NOLINT
      managedStore::GetManagedObjectStore()->GetIoContext();
  std::shared_ptr<ConnectionPolicy> connPolicy;  // NOLINT

  // Used as a dummy callback by sendData() in order to call
  // sendDataWithCallback()
  static void genericResHandler(const Response& res) {
    BMCWEB_LOG_DEBUG << "Response handled with return code: "
                     << std::to_string(res.resultInt());
  }

 public:
  HttpClient() = delete;
  explicit HttpClient(const std::shared_ptr<ConnectionPolicy>& connPolicyIn)
      : connPolicy(connPolicyIn) {}
  HttpClient(const HttpClient&) = delete;
  HttpClient& operator=(const HttpClient&) = delete;
  HttpClient(HttpClient&&) = delete;
  HttpClient& operator=(HttpClient&&) = delete;
  ~HttpClient() = default;

  // Send a request to destIP:destPort where additional processing of the
  // result is not required
  void sendData(std::string& data, const std::string& destIP, uint16_t destPort,
                const std::string& destUri, bool useSSL,
                const boost::beast::http::fields& httpHeader,
                const boost::beast::http::verb verb) {
    const std::function<void(Response&)> cb = genericResHandler;
    sendDataWithCallback(data, destIP, destPort, destUri, useSSL, httpHeader,
                         verb, cb);
  }

  // Send request to destIP:destPort and use the provided callback to
  // handle the response
  void sendDataWithCallback(std::string& data, const std::string& destIP,
                            uint16_t destPort, const std::string& destUri,
                            bool useSSL,
                            const boost::beast::http::fields& httpHeader,
                            const boost::beast::http::verb verb,
                            const std::function<void(Response&)>& resHandler) {
    std::string client_key = useSSL ? "https" : "http";
    client_key += destIP;
    client_key += ":";
    client_key += std::to_string(destPort);
    auto pool = connectionPools.try_emplace(client_key);
    if (pool.first->second == nullptr) {
      pool.first->second = std::make_shared<ConnectionPool>(
          ioc, client_key, connPolicy, destIP, destPort, useSSL);
    }
    // Send the data using either the existing connection pool or the newly
    // created connection pool
    pool.first->second->sendData(data, destUri, httpHeader, verb, resHandler);
  }
};
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_HTTP_HTTP_CLIENT_H_
