/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */

#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <cstddef>
#include <memory>
#include <string>

#include "cm_uv.h"

#include "cmUVHandlePtr.h"

class cmServerBase;

/***
 * Given a sequence of bytes with any kind of buffering, instances of this
 * class arrange logical chunks according to whatever the use case is for
 * the connection.
 */
class cmConnectionBufferStrategy
{
public:
  virtual ~cmConnectionBufferStrategy();

  /***
   * Called whenever with an active raw buffer. If a logical chunk
   * becomes available, that chunk is returned and that portion is
   * removed from the rawBuffer
   *
   * @param rawBuffer in/out parameter. Receive buffer; the buffer strategy is
   * free to manipulate this buffer anyway it needs to.
   *
   * @return Next chunk from the stream. Returns the empty string if a chunk
   * isn't ready yet. Users of this interface should repeatedly call this
   * function until an empty string is returned since its entirely possible
   * multiple chunks come in a single raw buffer.
   */
  virtual std::string BufferMessage(std::string& rawBuffer) = 0;

  /***
   * Called to properly buffer an outgoing message.
   *
   * @param rawBuffer Message to format in the correct way
   *
   * @return Formatted message
   */
  virtual std::string BufferOutMessage(const std::string& rawBuffer) const
  {
    return rawBuffer;
  };
  /***
   * Resets the internal state of the buffering
   */
  virtual void clear();

  // TODO: There should be a callback / flag set for errors
};

class cmConnection
{
public:
  cmConnection() = default;

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

  virtual void WriteData(const std::string& data) = 0;

  virtual ~cmConnection();

  virtual bool OnConnectionShuttingDown();

  virtual bool IsOpen() const = 0;

  virtual void SetServer(cmServerBase* s);

  virtual void ProcessRequest(const std::string& request);

  virtual bool OnServeStart(std::string* pString);

protected:
  cmServerBase* Server = nullptr;
};

/***
 * Abstraction of a connection; ties in event callbacks from libuv and notifies
 * the server when appropriate
 */
class cmEventBasedConnection : public cmConnection
{

public:
  /***
   * @param bufferStrategy If no strategy is given, it will process the raw
   * chunks as they come in. The connection
   * owns the pointer given.
   */
  cmEventBasedConnection(cmConnectionBufferStrategy* bufferStrategy = nullptr);

  virtual void Connect(uv_stream_t* server);

  virtual void ReadData(const std::string& data);

  bool IsOpen() const override;

  void WriteData(const std::string& data) override;
  bool OnConnectionShuttingDown() override;

  virtual void OnDisconnect(int errorCode);

  static void on_close(uv_handle_t* handle);

  template <typename T>
  static void on_close_delete(uv_handle_t* handle)
  {
    delete reinterpret_cast<T*>(handle);
  }

protected:
  cm::uv_stream_ptr WriteStream;

  std::string RawReadBuffer;

  std::unique_ptr<cmConnectionBufferStrategy> BufferStrategy;

  static void on_read(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);

  static void on_write(uv_write_t* req, int status);

  static void on_new_connection(uv_stream_t* stream, int status);

  static void on_alloc_buffer(uv_handle_t* handle, size_t suggested_size,
                              uv_buf_t* buf);
};
