/* 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
}
