/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#define cmUVHandlePtr_cxx
#include "cmUVHandlePtr.h"

#include <assert.h>
#include <mutex>
#include <stdlib.h>

#include "cm_uv.h"

namespace cm {

struct uv_loop_deleter
{
  void operator()(uv_loop_t* loop) const;
};

void uv_loop_deleter::operator()(uv_loop_t* loop) const
{
  uv_run(loop, UV_RUN_DEFAULT);
  int result = uv_loop_close(loop);
  (void)result;
  assert(result >= 0);
  free(loop);
}

int uv_loop_ptr::init(void* data)
{
  this->reset();

  this->loop.reset(static_cast<uv_loop_t*>(calloc(1, sizeof(uv_loop_t))),
                   uv_loop_deleter());
  this->loop->data = data;

  return uv_loop_init(this->loop.get());
}

void uv_loop_ptr::reset()
{
  this->loop.reset();
}

uv_loop_ptr::operator uv_loop_t*()
{
  return this->loop.get();
}

uv_loop_t* uv_loop_ptr::operator->() const noexcept
{
  return this->loop.get();
}

uv_loop_t* uv_loop_ptr::get() const
{
  return this->loop.get();
}

template <typename T>
static void handle_default_delete(T* type_handle)
{
  auto handle = reinterpret_cast<uv_handle_t*>(type_handle);
  if (handle) {
    assert(!uv_is_closing(handle));
    if (!uv_is_closing(handle)) {
      uv_close(handle, [](uv_handle_t* h) { free(h); });
    }
  }
}

/**
 * Encapsulates delete logic for a given handle type T
 */
template <typename T>
struct uv_handle_deleter
{
  void operator()(T* type_handle) const { handle_default_delete(type_handle); }
};

template <typename T>
void uv_handle_ptr_base_<T>::allocate(void* data)
{
  reset();

  /*
    We use calloc since we know all these types are c structs
    and we just want to 0 init them. New would do the same thing;
    but casting from uv_handle_t to certain other types -- namely
    uv_timer_t -- triggers a cast_align warning on certain systems.
  */
  handle.reset(static_cast<T*>(calloc(1, sizeof(T))), uv_handle_deleter<T>());
  handle->data = data;
}

template <typename T>
void uv_handle_ptr_base_<T>::reset()
{
  handle.reset();
}

template <typename T>
uv_handle_ptr_base_<T>::operator uv_handle_t*()
{
  return reinterpret_cast<uv_handle_t*>(handle.get());
}

template <typename T>
T* uv_handle_ptr_base_<T>::operator->() const noexcept
{
  return handle.get();
}

template <typename T>
T* uv_handle_ptr_base_<T>::get() const
{
  return handle.get();
}

template <typename T>
uv_handle_ptr_<T>::operator T*() const
{
  return this->handle.get();
}

#ifdef CMAKE_BUILD_WITH_CMAKE
template <>
struct uv_handle_deleter<uv_async_t>
{
  /***
   * Wile uv_async_send is itself thread-safe, there are
   * no strong guarantees that close hasn't already been
   * called on the handle; and that it might be deleted
   * as the send call goes through. This mutex guards
   * against that.
   *
   * The shared_ptr here is to allow for copy construction
   * which is mandated by the standard for Deleter on
   * shared_ptrs.
   */
  std::shared_ptr<std::mutex> handleMutex;

  uv_handle_deleter()
    : handleMutex(std::make_shared<std::mutex>())
  {
  }

  void operator()(uv_async_t* handle)
  {
    std::lock_guard<std::mutex> lock(*handleMutex);
    handle_default_delete(handle);
  }
};

void uv_async_ptr::send()
{
  auto deleter = std::get_deleter<uv_handle_deleter<uv_async_t>>(this->handle);
  assert(deleter);

  std::lock_guard<std::mutex> lock(*deleter->handleMutex);
  if (this->handle) {
    uv_async_send(*this);
  }
}

int uv_async_ptr::init(uv_loop_t& loop, uv_async_cb async_cb, void* data)
{
  allocate(data);
  return uv_async_init(&loop, handle.get(), async_cb);
}
#endif

template <>
struct uv_handle_deleter<uv_signal_t>
{
  void operator()(uv_signal_t* handle) const
  {
    if (handle) {
      uv_signal_stop(handle);
      handle_default_delete(handle);
    }
  }
};

int uv_signal_ptr::init(uv_loop_t& loop, void* data)
{
  allocate(data);
  return uv_signal_init(&loop, handle.get());
}

int uv_signal_ptr::start(uv_signal_cb cb, int signum)
{
  assert(handle);
  return uv_signal_start(*this, cb, signum);
}

void uv_signal_ptr::stop()
{
  if (handle) {
    uv_signal_stop(*this);
  }
}

int uv_pipe_ptr::init(uv_loop_t& loop, int ipc, void* data)
{
  allocate(data);
  return uv_pipe_init(&loop, *this, ipc);
}

uv_pipe_ptr::operator uv_stream_t*() const
{
  return reinterpret_cast<uv_stream_t*>(handle.get());
}

int uv_process_ptr::spawn(uv_loop_t& loop, uv_process_options_t const& options,
                          void* data)
{
  allocate(data);
  return uv_spawn(&loop, *this, &options);
}

int uv_timer_ptr::init(uv_loop_t& loop, void* data)
{
  allocate(data);
  return uv_timer_init(&loop, *this);
}

int uv_timer_ptr::start(uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
{
  assert(handle);
  return uv_timer_start(*this, cb, timeout, repeat);
}

#ifdef CMAKE_BUILD_WITH_CMAKE
uv_tty_ptr::operator uv_stream_t*() const
{
  return reinterpret_cast<uv_stream_t*>(handle.get());
}

int uv_tty_ptr::init(uv_loop_t& loop, int fd, int readable, void* data)
{
  allocate(data);
  return uv_tty_init(&loop, *this, fd, readable);
}
#endif

template class uv_handle_ptr_base_<uv_handle_t>;

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

UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(signal)

UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(pipe)

UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(stream)

UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(process)

UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(timer)

#ifdef CMAKE_BUILD_WITH_CMAKE
UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(async)

UV_HANDLE_PTR_INSTANTIATE_EXPLICIT(tty)
#endif
}
