/* 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 <cm3p/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 U>
  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_() { this->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 U>
  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);
};

using uv_stream_ptr = uv_handle_ptr_<uv_stream_t>;
using uv_handle_ptr = uv_handle_ptr_<uv_handle_t>;

#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
}
