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

#include "cm_uv.h"

#if defined(__SUNPRO_CC)

#  include <utility>

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

#else

#  define CM_INHERIT_CTOR(Class, Base, Tpl) using Base Tpl ::Base;

#endif

namespace cm {

/***
 * RAII class to simplify and ensure the safe usage of uv_loop_t. This includes
 * making sure resources are properly freed.
 */
class uv_loop_ptr
{
protected:
  std::shared_ptr<uv_loop_t> loop;

public:
  uv_loop_ptr(uv_loop_ptr const&) = delete;
  uv_loop_ptr& operator=(uv_loop_ptr const&) = delete;
  uv_loop_ptr(uv_loop_ptr&&) noexcept;
  uv_loop_ptr& operator=(uv_loop_ptr&&) noexcept;

  // Dtor and ctor need to be inline defined like this for default ctors and
  // dtors to work.  Some compilers do not like '= default' here.
  uv_loop_ptr() {} // NOLINT(modernize-use-equals-default)
  uv_loop_ptr(std::nullptr_t) {}
  ~uv_loop_ptr() { this->reset(); }

  int init(void* data = nullptr);

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

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

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

/***
 * RAII class to simplify and ensure 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:
  uv_handle_ptr_base_(uv_handle_ptr_base_ const&) = delete;
  uv_handle_ptr_base_& operator=(uv_handle_ptr_base_ const&) = delete;
  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.  Some compilers do not like '= default' here.
  uv_handle_ptr_base_() {} // NOLINT(modernize-use-equals-default)
  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_INHERIT_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_INHERIT_CTOR(uv_handle_ptr_, uv_handle_ptr_base_, <uv_handle_t>);
};

class uv_async_ptr : public uv_handle_ptr_<uv_async_t>
{
public:
  CM_INHERIT_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_INHERIT_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_INHERIT_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_INHERIT_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_INHERIT_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_INHERIT_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
}
