//===-- SBCommunication.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBCommunication.h"
#include "SBReproducerPrivate.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/Core/Communication.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"

using namespace lldb;
using namespace lldb_private;

SBCommunication::SBCommunication() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBCommunication);
}

SBCommunication::SBCommunication(const char *broadcaster_name)
    : m_opaque(new Communication(broadcaster_name)), m_opaque_owned(true) {
  LLDB_RECORD_CONSTRUCTOR(SBCommunication, (const char *), broadcaster_name);
}

SBCommunication::~SBCommunication() {
  if (m_opaque && m_opaque_owned)
    delete m_opaque;
  m_opaque = nullptr;
  m_opaque_owned = false;
}

bool SBCommunication::IsValid() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsValid);
  return this->operator bool();
}
SBCommunication::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, operator bool);

  return m_opaque != nullptr;
}

bool SBCommunication::GetCloseOnEOF() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, GetCloseOnEOF);

  if (m_opaque)
    return m_opaque->GetCloseOnEOF();
  return false;
}

void SBCommunication::SetCloseOnEOF(bool b) {
  LLDB_RECORD_METHOD(void, SBCommunication, SetCloseOnEOF, (bool), b);

  if (m_opaque)
    m_opaque->SetCloseOnEOF(b);
}

ConnectionStatus SBCommunication::Connect(const char *url) {
  LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication, Connect,
                     (const char *), url);

  if (m_opaque) {
    if (!m_opaque->HasConnection())
      m_opaque->SetConnection(Host::CreateDefaultConnection(url));
    return m_opaque->Connect(url, nullptr);
  }
  return eConnectionStatusNoConnection;
}

ConnectionStatus SBCommunication::AdoptFileDesriptor(int fd, bool owns_fd) {
  LLDB_RECORD_METHOD(lldb::ConnectionStatus, SBCommunication,
                     AdoptFileDesriptor, (int, bool), fd, owns_fd);

  ConnectionStatus status = eConnectionStatusNoConnection;
  if (m_opaque) {
    if (m_opaque->HasConnection()) {
      if (m_opaque->IsConnected())
        m_opaque->Disconnect();
    }
    m_opaque->SetConnection(
        std::make_unique<ConnectionFileDescriptor>(fd, owns_fd));
    if (m_opaque->IsConnected())
      status = eConnectionStatusSuccess;
    else
      status = eConnectionStatusLostConnection;
  }
  return status;
}

ConnectionStatus SBCommunication::Disconnect() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::ConnectionStatus, SBCommunication,
                             Disconnect);

  ConnectionStatus status = eConnectionStatusNoConnection;
  if (m_opaque)
    status = m_opaque->Disconnect();
  return status;
}

bool SBCommunication::IsConnected() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBCommunication, IsConnected);

  return m_opaque ? m_opaque->IsConnected() : false;
}

size_t SBCommunication::Read(void *dst, size_t dst_len, uint32_t timeout_usec,
                             ConnectionStatus &status) {
  LLDB_RECORD_DUMMY(size_t, SBCommunication, Read,
                    (void *, size_t, uint32_t, lldb::ConnectionStatus &), dst,
                    dst_len, timeout_usec, status);

  size_t bytes_read = 0;
  Timeout<std::micro> timeout = timeout_usec == UINT32_MAX
                                    ? Timeout<std::micro>(llvm::None)
                                    : std::chrono::microseconds(timeout_usec);
  if (m_opaque)
    bytes_read = m_opaque->Read(dst, dst_len, timeout, status, nullptr);
  else
    status = eConnectionStatusNoConnection;

  return bytes_read;
}

size_t SBCommunication::Write(const void *src, size_t src_len,
                              ConnectionStatus &status) {
  LLDB_RECORD_DUMMY(size_t, SBCommunication, Write,
                    (const void *, size_t, lldb::ConnectionStatus &), src,
                    src_len, status);

  size_t bytes_written = 0;
  if (m_opaque)
    bytes_written = m_opaque->Write(src, src_len, status, nullptr);
  else
    status = eConnectionStatusNoConnection;

  return bytes_written;
}

bool SBCommunication::ReadThreadStart() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStart);

  return m_opaque ? m_opaque->StartReadThread() : false;
}

bool SBCommunication::ReadThreadStop() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadStop);

  return m_opaque ? m_opaque->StopReadThread() : false;
}

bool SBCommunication::ReadThreadIsRunning() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBCommunication, ReadThreadIsRunning);

  return m_opaque ? m_opaque->ReadThreadIsRunning() : false;
}

bool SBCommunication::SetReadThreadBytesReceivedCallback(
    ReadThreadBytesReceived callback, void *callback_baton) {
  LLDB_RECORD_DUMMY(bool, SBCommunication, SetReadThreadBytesReceivedCallback,
                    (lldb::SBCommunication::ReadThreadBytesReceived, void *),
                    callback, callback_baton);

  bool result = false;
  if (m_opaque) {
    m_opaque->SetReadThreadBytesReceivedCallback(callback, callback_baton);
    result = true;
  }
  return result;
}

SBBroadcaster SBCommunication::GetBroadcaster() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBCommunication,
                             GetBroadcaster);

  SBBroadcaster broadcaster(m_opaque, false);
  return LLDB_RECORD_RESULT(broadcaster);
}

const char *SBCommunication::GetBroadcasterClass() {
  LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBCommunication,
                                    GetBroadcasterClass);

  return Communication::GetStaticBroadcasterClass().AsCString();
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBCommunication>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBCommunication, ());
  LLDB_REGISTER_CONSTRUCTOR(SBCommunication, (const char *));
  LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, operator bool, ());
  LLDB_REGISTER_METHOD(bool, SBCommunication, GetCloseOnEOF, ());
  LLDB_REGISTER_METHOD(void, SBCommunication, SetCloseOnEOF, (bool));
  LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, Connect,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication,
                       AdoptFileDesriptor, (int, bool));
  LLDB_REGISTER_METHOD(lldb::ConnectionStatus, SBCommunication, Disconnect,
                       ());
  LLDB_REGISTER_METHOD_CONST(bool, SBCommunication, IsConnected, ());
  LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadStart, ());
  LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadStop, ());
  LLDB_REGISTER_METHOD(bool, SBCommunication, ReadThreadIsRunning, ());
  LLDB_REGISTER_METHOD(lldb::SBBroadcaster, SBCommunication, GetBroadcaster,
                       ());
  LLDB_REGISTER_STATIC_METHOD(const char *, SBCommunication,
                              GetBroadcasterClass, ());
}

}
}
