/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmDebuggerPosixPipeConnection.h"

#include <cerrno>
#include <cstring>
#include <stdexcept>
#include <utility>

#include <unistd.h>

#include <sys/socket.h>

namespace cmDebugger {

#ifndef _WIN32

cmDebuggerPipeConnection_POSIX::cmDebuggerPipeConnection_POSIX(
  std::string name)
  : PipeName(std::move(name))
{
  addr.sun_path[0] = '\0';
}

cmDebuggerPipeConnection_POSIX::~cmDebuggerPipeConnection_POSIX()
{
  if (isOpen()) {
    close();
  }
}

bool cmDebuggerPipeConnection_POSIX::StartListening(std::string& errorMessage)
{
  listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (listen_fd < 0) {
    errorMessage = "Failed to create socket: ";
    errorMessage += strerror(errno);
    return false;
  }

  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
  addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
  if (bind(listen_fd, (sockaddr*)&addr, sizeof(addr)) == -1) {
    errorMessage = "Failed to bind name '";
    errorMessage += addr.sun_path;
    errorMessage += "' to socket: ";
    errorMessage += strerror(errno);
    close_listen();
    return false;
  }

  if (listen(listen_fd, 1) == -1) {
    errorMessage = "Failed to listen on socket: ";
    errorMessage += strerror(errno);
    close_listen();
    return false;
  }

  StartedListening.set_value();
  return true;
}

std::shared_ptr<dap::Reader> cmDebuggerPipeConnection_POSIX::GetReader()
{
  return std::static_pointer_cast<dap::Reader>(shared_from_this());
}

std::shared_ptr<dap::Writer> cmDebuggerPipeConnection_POSIX::GetWriter()
{
  return std::static_pointer_cast<dap::Writer>(shared_from_this());
}

bool cmDebuggerPipeConnection_POSIX::isOpen()
{
  return rw_pipe >= 0;
}

void cmDebuggerPipeConnection_POSIX::close()
{
  close_listen();
  ::close(rw_pipe);
  rw_pipe = -1;
}

void cmDebuggerPipeConnection_POSIX::close_listen()
{
  if (strlen(addr.sun_path) > 0) {
    unlink(addr.sun_path);
    addr.sun_path[0] = '\0';
  }
  ::close(listen_fd);
  listen_fd = -1;
}

void cmDebuggerPipeConnection_POSIX::WaitForConnection()
{
  sockaddr_un laddr;
  socklen_t len = sizeof(laddr);
  rw_pipe = accept(listen_fd, (sockaddr*)&laddr, &len);
  if (rw_pipe < 0) {
    close();
    return;
  }

  close_listen(); // no longer need the listen resources
}

size_t cmDebuggerPipeConnection_POSIX::read(void* buffer, size_t n)
{
  size_t result = 0;
  if (rw_pipe >= 0) {
    result = ::read(rw_pipe, buffer, n);
    if (result == 0) {
      close();
    }
  }

  return result;
}

bool cmDebuggerPipeConnection_POSIX::write(void const* buffer, size_t n)
{
  bool result = false;
  if (rw_pipe >= 0) {
    result = ::write(rw_pipe, buffer, n) >= 0;
    if (!result) {
      close();
    }
  }

  return result;
}

cmDebuggerPipeClient_POSIX::cmDebuggerPipeClient_POSIX(std::string name)
  : PipeName(std::move(name))
{
}

cmDebuggerPipeClient_POSIX::~cmDebuggerPipeClient_POSIX()
{
  close();
}

void cmDebuggerPipeClient_POSIX::WaitForConnection()
{
  rw_pipe = socket(AF_UNIX, SOCK_STREAM, 0);
  if (rw_pipe < 0) {
    throw std::runtime_error(std::string("Failed to create socket: ") +
                             strerror(errno));
  }

  sockaddr_un addr;
  addr.sun_family = AF_UNIX;
  strncpy(addr.sun_path, PipeName.c_str(), sizeof(addr.sun_path));
  addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
  if (connect(rw_pipe, (sockaddr*)&addr, sizeof(addr)) == -1) {
    close();
    throw std::runtime_error(
      std::string("Failed to connect path to socket: ") + strerror(errno));
  }
}

bool cmDebuggerPipeClient_POSIX::isOpen()
{
  return rw_pipe >= 0;
}

void cmDebuggerPipeClient_POSIX::close()
{
  if (isOpen()) {
    ::close(rw_pipe);
    rw_pipe = -1;
  }
}

size_t cmDebuggerPipeClient_POSIX::read(void* buffer, size_t n)
{
  int count = 0;
  if (isOpen()) {
    count = static_cast<int>(::read(rw_pipe, buffer, n));
    if (count == 0) {
      close();
    }
  }

  return count;
}

bool cmDebuggerPipeClient_POSIX::write(void const* buffer, size_t n)
{
  int count = 0;
  if (isOpen()) {
    count = static_cast<int>(::write(rw_pipe, buffer, n));
    if (count < 0) {
      close();
    }
  }

  return count > 0;
}

#endif // !_WIN32

} // namespace cmDebugger
