#ifndef THIRD_PARTY_GBMCWEB_INCLUDE_VM_WEBSOCKET_H_
#define THIRD_PARTY_GBMCWEB_INCLUDE_VM_WEBSOCKET_H_

#include <cerrno>
#include <csignal>
#include <cstddef>
#include <memory>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT

#include "boost/beast/core/flat_static_buffer.hpp"  // NOLINT
#include "boost/process/async_pipe.hpp"  // NOLINT
#include "boost/process/child.hpp"  // NOLINT
#include "boost/process/io.hpp"  // NOLINT
#include "app.hpp"
#include "logging.hpp"
#include "websocket.hpp"

namespace crow {
namespace obmc_vm {

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static crow::websocket::Connection* session = nullptr;

// The max network block device buffer size is 128kb plus 16bytes
// for the message header:
// https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md#simple-reply-message
static constexpr auto nbdBufferSize = (128 * 1024 + 16) * 4;

class Handler : public std::enable_shared_from_this<Handler> {
 public:
  Handler(const std::string& mediaIn, boost::asio::io_context& ios)
      : pipeOut(ios),
        pipeIn(ios),
        media(mediaIn),
        outputBuffer(new boost::beast::flat_static_buffer<nbdBufferSize>),
        inputBuffer(new boost::beast::flat_static_buffer<nbdBufferSize>) {}

  ~Handler() = default;

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

  void doClose() {
    // boost::process::child::terminate uses SIGKILL, need to send SIGTERM
    // to allow the proxy to stop nbd-client and the USB device gadget.
    int rc = kill(proxy.id(), SIGTERM);
    if (rc != 0) {
      BMCWEB_LOG_ERROR << "Failed to terminate nbd-proxy: " << errno;
      return;
    }

    proxy.wait();
  }

  void connect() {
    std::error_code ec;
    proxy = boost::process::child("/usr/sbin/nbd-proxy", media,
                                  boost::process::std_out > pipeOut,
                                  boost::process::std_in < pipeIn, ec);
    if (ec) {
      BMCWEB_LOG_ERROR << "Couldn't connect to nbd-proxy: " << ec.message();
      if (session != nullptr) {
        session->close("Error connecting to nbd-proxy");
      }
      return;
    }
    doWrite();
    doRead();
  }

  void doWrite() {
    if (doingWrite) {
      BMCWEB_LOG_DEBUG << "Already writing.  Bailing out";
      return;
    }

    if (inputBuffer->size() == 0) {
      BMCWEB_LOG_DEBUG << "inputBuffer empty.  Bailing out";
      return;
    }

    doingWrite = true;
    pipeIn.async_write_some(
        inputBuffer->data(),
        [this, self(shared_from_this())](boost::beast::error_code ec,
                                         std::size_t bytesWritten) {
          BMCWEB_LOG_DEBUG << "Wrote " << bytesWritten << "bytes";
          doingWrite = false;
          inputBuffer->consume(bytesWritten);

          if (session == nullptr) {
            return;
          }
          if (ec == boost::asio::error::eof) {
            session->close("VM socket port closed");
            return;
          }
          if (ec) {
            session->close("Error in writing to proxy port");
            BMCWEB_LOG_ERROR << "Error in VM socket write " << ec;
            return;
          }
          doWrite();
        });
  }

  void doRead() {
    std::size_t bytes = outputBuffer->capacity() - outputBuffer->size();

    pipeOut.async_read_some(
        outputBuffer->prepare(bytes),
        [this, self(shared_from_this())](const boost::system::error_code& ec,
                                         std::size_t bytesRead) {
          BMCWEB_LOG_DEBUG << "Read done.  Read " << bytesRead << " bytes";
          if (ec) {
            BMCWEB_LOG_ERROR << "Couldn't read from VM port: " << ec;
            if (session != nullptr) {
              session->close("Error in connecting to VM port");
            }
            return;
          }
          if (session == nullptr) {
            return;
          }

          outputBuffer->commit(bytesRead);
          std::string_view payload(
              static_cast<const char*>(outputBuffer->data().data()), bytesRead);
          session->sendBinary(payload);
          outputBuffer->consume(bytesRead);

          doRead();
        });
  }

  boost::process::async_pipe pipeOut;
  boost::process::async_pipe pipeIn;
  boost::process::child proxy;
  std::string media;
  bool doingWrite{false};

  std::unique_ptr<boost::beast::flat_static_buffer<nbdBufferSize>> outputBuffer;
  std::unique_ptr<boost::beast::flat_static_buffer<nbdBufferSize>> inputBuffer;
};

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static std::shared_ptr<Handler> handler;

inline void requestRoutes(App& app) {
  BMCWEB_ROUTE(app, "/vm/0/0")
      .privileges({{"ConfigureComponents", "ConfigureManager"}})
      .websocket()
      .onopen([](crow::websocket::Connection& conn) {
        BMCWEB_LOG_DEBUG << "Connection " << &conn << " opened";

        if (session != nullptr) {
          conn.close("Session already connected");
          return;
        }

        if (handler != nullptr) {
          conn.close("Handler already running");
          return;
        }

        session = &conn;

        // media is the last digit of the endpoint /vm/0/0. A future
        // enhancement can include supporting different endpoint values.
        const char* media = "0";
        handler = std::make_shared<Handler>(media, conn.getIoContext());
        handler->connect();
      })
      .onclose(
          [](crow::websocket::Connection& conn, const std::string& /*reason*/) {
            if (&conn != session) {
              return;
            }

            session = nullptr;
            handler->doClose();
            handler->inputBuffer->clear();
            handler->outputBuffer->clear();
            handler.reset();
          })
      .onmessage([](crow::websocket::Connection& conn, const std::string& data,
                    bool) {
        if (data.length() >
            handler->inputBuffer->capacity() - handler->inputBuffer->size()) {
          BMCWEB_LOG_ERROR << "Buffer overrun when writing " << data.length()
                           << " bytes";
          conn.close("Buffer overrun");
          return;
        }

        boost::asio::buffer_copy(handler->inputBuffer->prepare(data.size()),
                                 boost::asio::buffer(data));
        handler->inputBuffer->commit(data.size());
        handler->doWrite();
      });
}

}  // namespace obmc_vm
}  // namespace crow

#endif  // THIRD_PARTY_GBMCWEB_INCLUDE_VM_WEBSOCKET_H_
