/* 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 <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <type_traits>

#include "cm_uv.h"

#define CM_PERFECT_FWD_CTOR(Class, FwdTo)                                     \
  template <typename... Args>                                                 \
  Class(Args&&... args)                                                       \
    : FwdTo(std::forward<Args>(args)...)                                      \
  {                                                                           \
  }

namespace cm {

/***
* RAII class to simplify and insure the safe usage of uv_*_t types. This
* includes making sure resources are properly freed and contains casting
* operators which allow for passing into relevant uv_* functions.
*
*@tparam T actual uv_*_t type represented.
*/
template <typename T>
class uv_handle_ptr_base_
{
protected:
  template <typename _T>
  friend class uv_handle_ptr_base_;

  /**
   * This must be a pointer type since the handle can outlive this class.
   * When uv_close is eventually called on the handle, the memory the
   * handle inhabits must be valid until the close callback is called
   * which can be later on in the loop.
   */
  std::shared_ptr<T> handle;

  /**
   * Allocate memory for the type and optionally set it's 'data' pointer.
   * Protected since this should only be called for an appropriate 'init'
   * call.
   *
   * @param data data pointer to set
   */
  void allocate(void* data = nullptr);

public:
  CM_DISABLE_COPY(uv_handle_ptr_base_)
  uv_handle_ptr_base_(uv_handle_ptr_base_&&) noexcept;
  uv_handle_ptr_base_& operator=(uv_handle_ptr_base_&&) noexcept;

  /**
   * This move constructor allows us to move out of a more specialized
   * uv type into a less specialized one. The only constraint is that
   * the right hand side is castable to T.
   *
   * This allows you to return uv_handle_ptr or uv_stream_ptr from a function
   * that initializes something like uv_pipe_ptr or uv_tcp_ptr and interact
   * and clean up after it without caring about the exact type.
   */
  template <typename S, typename = typename std::enable_if<
                          std::is_rvalue_reference<S&&>::value>::type>
  uv_handle_ptr_base_(S&& rhs)
  {
    // This will force a compiler error if rhs doesn't have a casting
    // operator to get T*
    this->handle = std::shared_ptr<T>(rhs.handle, rhs);
    rhs.handle.reset();
  }

  // Dtor and ctor need to be inline defined like this for default ctors and
  // dtors to work.
  uv_handle_ptr_base_() {}
  uv_handle_ptr_base_(std::nullptr_t) {}
  ~uv_handle_ptr_base_() { reset(); }

  /**
   * Properly close the handle if needed and sets the inner handle to nullptr
   */
  void reset();

  /**
   * Allow less verbose calling of uv_handle_* functions
   * @return reinterpreted handle
   */
  operator uv_handle_t*();

  T* get() const;
  T* operator->() const noexcept;
};

template <typename T>
inline uv_handle_ptr_base_<T>::uv_handle_ptr_base_(
  uv_handle_ptr_base_<T>&&) noexcept = default;
template <typename T>
inline uv_handle_ptr_base_<T>& uv_handle_ptr_base_<T>::operator=(
  uv_handle_ptr_base_<T>&&) noexcept = default;

/**
 * While uv_handle_ptr_base_ only exposes uv_handle_t*, this exposes uv_T_t*
 * too. It is broken out like this so we can reuse most of the code for the
 * uv_handle_ptr class.
 */
template <typename T>
class uv_handle_ptr_ : public uv_handle_ptr_base_<T>
{
  template <typename _T>
  friend class uv_handle_ptr_;

public:
  CM_PERFECT_FWD_CTOR(uv_handle_ptr_, uv_handle_ptr_base_<T>);

  /***
   * Allow less verbose calling of uv_<T> functions
   * @return reinterpreted handle
   */
  operator T*() const;
};

/***
 * This specialization is required to avoid duplicate 'operator uv_handle_t*()'
 * declarations
 */
template <>
class uv_handle_ptr_<uv_handle_t> : public uv_handle_ptr_base_<uv_handle_t>
{
public:
  CM_PERFECT_FWD_CTOR(uv_handle_ptr_, uv_handle_ptr_base_<uv_handle_t>);
};

class uv_async_ptr : public uv_handle_ptr_<uv_async_t>
{
public:
  CM_PERFECT_FWD_CTOR(uv_async_ptr, uv_handle_ptr_<uv_async_t>);

  int init(uv_loop_t& loop, uv_async_cb async_cb, void* data = nullptr);

  void send();
};

struct uv_signal_ptr : public uv_handle_ptr_<uv_signal_t>
{
  CM_PERFECT_FWD_CTOR(uv_signal_ptr, uv_handle_ptr_<uv_signal_t>);

  int init(uv_loop_t& loop, void* data = nullptr);

  int start(uv_signal_cb cb, int signum);

  void stop();
};

struct uv_pipe_ptr : public uv_handle_ptr_<uv_pipe_t>
{
  CM_PERFECT_FWD_CTOR(uv_pipe_ptr, uv_handle_ptr_<uv_pipe_t>);

  operator uv_stream_t*() const;

  int init(uv_loop_t& loop, int ipc, void* data = nullptr);
};

struct uv_process_ptr : public uv_handle_ptr_<uv_process_t>
{
  CM_PERFECT_FWD_CTOR(uv_process_ptr, uv_handle_ptr_<uv_process_t>);

  int spawn(uv_loop_t& loop, uv_process_options_t const& options,
            void* data = nullptr);
};

struct uv_timer_ptr : public uv_handle_ptr_<uv_timer_t>
{
  CM_PERFECT_FWD_CTOR(uv_timer_ptr, uv_handle_ptr_<uv_timer_t>);

  int init(uv_loop_t& loop, void* data = nullptr);

  int start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat);
};

struct uv_tty_ptr : public uv_handle_ptr_<uv_tty_t>
{
  CM_PERFECT_FWD_CTOR(uv_tty_ptr, uv_handle_ptr_<uv_tty_t>);

  operator uv_stream_t*() const;

  int init(uv_loop_t& loop, int fd, int readable, void* data = nullptr);
};

typedef uv_handle_ptr_<uv_stream_t> uv_stream_ptr;
typedef uv_handle_ptr_<uv_handle_t> uv_handle_ptr;

#ifndef cmUVHandlePtr_cxx

extern template class uv_handle_ptr_base_<uv_handle_t>;

#define UV_HANDLE_PTR_INSTANTIATE_EXTERN(NAME)                                \
  extern template class uv_handle_ptr_base_<uv_##NAME##_t>;                   \
  extern template class uv_handle_ptr_<uv_##NAME##_t>;

UV_HANDLE_PTR_INSTANTIATE_EXTERN(async)

UV_HANDLE_PTR_INSTANTIATE_EXTERN(signal)

UV_HANDLE_PTR_INSTANTIATE_EXTERN(pipe)

UV_HANDLE_PTR_INSTANTIATE_EXTERN(process)

UV_HANDLE_PTR_INSTANTIATE_EXTERN(stream)

UV_HANDLE_PTR_INSTANTIATE_EXTERN(timer)

UV_HANDLE_PTR_INSTANTIATE_EXTERN(tty)

#undef UV_HANDLE_PTR_INSTANTIATE_EXTERN

#endif
}
