#ifndef THIRD_PARTY_GBMCWEB_HTTP_WEBSOCKET_H_
#define THIRD_PARTY_GBMCWEB_HTTP_WEBSOCKET_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <string_view>
#include <utility>

#include "boost/asio/buffer.hpp"  // NOLINT
#include "boost/beast/core/multi_buffer.hpp"  // NOLINT
#include "boost/beast/websocket.hpp"  // NOLINT
#include "http_request.hpp"
#include "logging.hpp"
#include "utility.hpp"
#include "sessions.hpp"

#ifdef BMCWEB_ENABLE_SSL
#include "boost/beast/websocket/ssl.hpp"  // NOLINT
#endif

namespace crow {
namespace websocket {

enum class MessageType : std::uint8_t {
  Binary,
  Text,
};

struct Connection : std::enable_shared_from_this<Connection> {
 public:
  explicit Connection(const crow::Request& reqIn) : req(reqIn.req) {}

  Connection(const Connection&) = delete;
  Connection(Connection&&) = delete;
  Connection& operator=(const Connection&) = delete;
  Connection& operator=(const Connection&&) = delete;

  virtual void sendBinary(std::string_view msg) = 0;
  virtual void sendBinary(std::string&& msg) = 0;
  virtual void sendEx(MessageType type, std::string_view msg,
                      std::function<void()>&& onDone) = 0;
  virtual void sendText(std::string_view msg) = 0;
  virtual void sendText(std::string&& msg) = 0;
  virtual void close(std::string_view msg) = 0;
  virtual void deferRead() = 0;
  virtual void resumeRead() = 0;
  virtual boost::asio::io_context& getIoContext() = 0;
  virtual ~Connection() = default;

  boost::beast::http::request<boost::beast::http::string_body> req;
};

template <typename Adaptor>
class ConnectionImpl : public Connection {
 public:
  ConnectionImpl(
      const crow::Request& reqIn, Adaptor adaptorIn,
      std::function<void(Connection&)> openHandlerIn,
      std::function<void(Connection&, const std::string&, bool)>
          messageHandlerIn,
      std::function<void(crow::websocket::Connection&, std::string_view,
                         crow::websocket::MessageType type,
                         std::function<void()>&& whenComplete)>
          messageExHandlerIn,
      std::function<void(Connection&, const std::string&)> closeHandlerIn,
      std::function<void(Connection&)> errorHandlerIn)
      : Connection(reqIn),
        ws(std::move(adaptorIn)),
        inBuffer(inString, 131088),
        openHandler(std::move(openHandlerIn)),
        messageHandler(std::move(messageHandlerIn)),
        messageExHandler(std::move(messageExHandlerIn)),
        closeHandler(std::move(closeHandlerIn)),
        errorHandler(std::move(errorHandlerIn)),
        session(reqIn.session) {
    /* Turn on the timeouts on websocket stream to server role */
    ws.set_option(boost::beast::websocket::stream_base::timeout::suggested(
        boost::beast::role_type::server));
    BMCWEB_LOG_DEBUG << "Creating new connection " << this;
  }

  boost::asio::io_context& getIoContext() override {
    return static_cast<boost::asio::io_context&>(ws.get_executor().context());
  }

  void start() {
    BMCWEB_LOG_DEBUG << "starting connection " << this;

    using bf = boost::beast::http::field;

    std::string_view protocol = req[bf::sec_websocket_protocol];

    ws.set_option(boost::beast::websocket::stream_base::decorator(
        [session{session}, protocol{std::string(protocol)}](
            boost::beast::websocket::response_type& m) {
#ifndef BMCWEB_INSECURE_DISABLE_CSRF_PREVENTION
          if (session != nullptr) {
            // use protocol for csrf checking
            if (session->cookieAuth &&
                !crow::utility::constantTimeStringCompare(protocol,
                                                          session->csrfToken)) {
              BMCWEB_LOG_ERROR << "Websocket CSRF error";
              m.result(boost::beast::http::status::unauthorized);
              return;
            }
          }
#endif
          if (!protocol.empty()) {
            m.insert(bf::sec_websocket_protocol, protocol);
          }

          m.insert(bf::strict_transport_security,
                   "max-age=31536000; "
                   "includeSubdomains; "
                   "preload");
          m.insert(bf::pragma, "no-cache");
          m.insert(bf::cache_control, "no-Store,no-Cache");
          m.insert("Content-Security-Policy", "default-src 'self'");
          m.insert("X-XSS-Protection",
                   "1; "
                   "mode=block");
          m.insert("X-Content-Type-Options", "nosniff");
        }));

    // Perform the websocket upgrade
    ws.async_accept(req, [this, self(shared_from_this())](
                             const boost::system::error_code& ec) {
      if (ec) {
        BMCWEB_LOG_ERROR << "Error in ws.async_accept " << ec;
        return;
      }
      acceptDone();
    });
  }

  void sendBinary(std::string_view msg) override {
    ws.binary(true);
    outBuffer.commit(boost::asio::buffer_copy(outBuffer.prepare(msg.size()),
                                              boost::asio::buffer(msg)));
    doWrite();
  }

  void sendEx(MessageType type, std::string_view msg,
              std::function<void()>&& onDone) override {
    if (doingWrite) {
      BMCWEB_LOG_CRITICAL
          << "Cannot mix sendEx usage with sendBinary or sendText";
      onDone();
      return;
    }
    ws.binary(type == MessageType::Binary);

    ws.async_write(boost::asio::buffer(msg),
                   [weak(weak_from_this()), onDone{std::move(onDone)}](
                       const boost::beast::error_code& ec, size_t) {
                     std::shared_ptr<Connection> self = weak.lock();

                     // Call the done handler regardless of whether we
                     // errored, but before we close things out
                     onDone();

                     if (ec) {
                       BMCWEB_LOG_ERROR << "Error in ws.async_write " << ec;
                       self->close("write error");
                     }
                   });
  }

  void sendBinary(std::string&& msg) override {
    ws.binary(true);
    outBuffer.commit(boost::asio::buffer_copy(outBuffer.prepare(msg.size()),
                                              boost::asio::buffer(msg)));
    doWrite();
  }

  void sendText(std::string_view msg) override {
    ws.text(true);
    outBuffer.commit(boost::asio::buffer_copy(outBuffer.prepare(msg.size()),
                                              boost::asio::buffer(msg)));
    doWrite();
  }

  void sendText(std::string&& msg) override {
    ws.text(true);
    outBuffer.commit(boost::asio::buffer_copy(outBuffer.prepare(msg.size()),
                                              boost::asio::buffer(msg)));
    doWrite();
  }

  void close(std::string_view msg) override {
    ws.async_close(
        {boost::beast::websocket::close_code::normal, msg},
        [self(shared_from_this())](const boost::system::error_code& ec) {
          if (ec == boost::asio::error::operation_aborted) {
            return;
          }
          if (ec) {
            BMCWEB_LOG_ERROR << "Error closing websocket " << ec;
            return;
          }
        });
  }

  void acceptDone() {
    BMCWEB_LOG_DEBUG << "Websocket accepted connection";

    if (openHandler) {
      openHandler(*this);
    }
    doRead();
  }

  void deferRead() override {
    readingDefered = true;

    // If we're not actively reading, we need to take ownership of
    // ourselves for a small portion of time, do that, and clear when we
    // resume.
    selfOwned = shared_from_this();
  }

  void resumeRead() override {
    readingDefered = false;
    doRead();

    // No longer need to keep ourselves alive now that read is active.
    selfOwned.reset();
  }

  void doRead() {
    if (readingDefered) {
      return;
    }
    ws.async_read(inBuffer,
                  [this, self(shared_from_this())](
                      const boost::beast::error_code& ec, size_t bytesRead) {
                    if (ec) {
                      if (ec != boost::beast::websocket::error::closed) {
                        BMCWEB_LOG_ERROR << "doRead error " << ec;
                      }
                      if (closeHandler) {
                        std::string reason{ws.reason().reason.c_str()};
                        closeHandler(*this, reason);
                      }
                      return;
                    }

                    handleMessage(bytesRead);
                  });
  }
  void doWrite() {
    // If we're already doing a write, ignore the request, it will be picked
    // up when the current write is complete
    if (doingWrite) {
      return;
    }

    if (outBuffer.size() == 0) {
      // Done for now
      return;
    }
    doingWrite = true;
    ws.async_write(outBuffer.data(),
                   [this, self(shared_from_this())](
                       const boost::beast::error_code& ec, size_t bytesSent) {
                     doingWrite = false;
                     outBuffer.consume(bytesSent);
                     if (ec == boost::beast::websocket::error::closed) {
                       // Do nothing here.  doRead handler will call the
                       // closeHandler.
                       close("Write error");
                       return;
                     }
                     if (ec) {
                       BMCWEB_LOG_ERROR << "Error in ws.async_write " << ec;
                       return;
                     }
                     doWrite();
                   });
  }

 private:
  void handleMessage(size_t bytesRead) {
    if (messageExHandler) {
      // Note, because of the interactions with the read buffers,
      // this message handler overrides the normal message handler
      messageExHandler(*this, inString, MessageType::Binary,
                       [this, self(shared_from_this()), bytesRead]() {
                         if (self == nullptr) {
                           return;
                         }

                         inBuffer.consume(bytesRead);
                         inString.clear();

                         doRead();
                       });
      return;
    }

    if (messageHandler) {
      messageHandler(*this, inString, ws.got_text());
    }
    inBuffer.consume(bytesRead);
    inString.clear();
    doRead();
  }
  // NOLINTBEGIN
  boost::beast::websocket::stream<Adaptor, false> ws;

  bool readingDefered = false;
  std::string inString;
  boost::asio::dynamic_string_buffer<std::string::value_type,
                                     std::string::traits_type,
                                     std::string::allocator_type>
      inBuffer;

  boost::beast::multi_buffer outBuffer;
  bool doingWrite = false;

  std::function<void(Connection&)> openHandler;
  std::function<void(Connection&, const std::string&, bool)> messageHandler;
  std::function<void(crow::websocket::Connection&, std::string_view,
                     crow::websocket::MessageType type,
                     std::function<void()>&& whenComplete)>
      messageExHandler;
  std::function<void(Connection&, const std::string&)> closeHandler;
  std::function<void(Connection&)> errorHandler;
  std::shared_ptr<persistent_data::UserSession> session;

  std::shared_ptr<Connection> selfOwned;
  // NOLINTEND
};
}  // namespace websocket
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_HTTP_WEBSOCKET_H_
