//===-- GDBRemoteClientBase.cpp ---------------------------------*- C++ -*-===//
//
// 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 "GDBRemoteClientBase.h"

#include "llvm/ADT/StringExtras.h"

#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/LLDBAssert.h"

#include "ProcessGDBRemoteLog.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
using namespace std::chrono;

static const seconds kInterruptTimeout(5);

/////////////////////////
// GDBRemoteClientBase //
/////////////////////////

GDBRemoteClientBase::ContinueDelegate::~ContinueDelegate() = default;

GDBRemoteClientBase::GDBRemoteClientBase(const char *comm_name,
                                         const char *listener_name)
    : GDBRemoteCommunication(comm_name, listener_name), m_async_count(0),
      m_is_running(false), m_should_stop(false) {}

StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse(
    ContinueDelegate &delegate, const UnixSignals &signals,
    llvm::StringRef payload, StringExtractorGDBRemote &response) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
  response.Clear();

  {
    std::lock_guard<std::mutex> lock(m_mutex);
    m_continue_packet = payload;
    m_should_stop = false;
  }
  ContinueLock cont_lock(*this);
  if (!cont_lock)
    return eStateInvalid;
  OnRunPacketSent(true);

  for (;;) {
    PacketResult read_result = ReadPacket(response, kInterruptTimeout, false);
    switch (read_result) {
    case PacketResult::ErrorReplyTimeout: {
      std::lock_guard<std::mutex> lock(m_mutex);
      if (m_async_count == 0)
        continue;
      if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout)
        return eStateInvalid;
      break;
    }
    case PacketResult::Success:
      break;
    default:
      LLDB_LOGF(log, "GDBRemoteClientBase::%s () ReadPacket(...) => false",
                __FUNCTION__);
      return eStateInvalid;
    }
    if (response.Empty())
      return eStateInvalid;

    const char stop_type = response.GetChar();
    LLDB_LOGF(log, "GDBRemoteClientBase::%s () got packet: %s", __FUNCTION__,
              response.GetStringRef().data());

    switch (stop_type) {
    case 'W':
    case 'X':
      return eStateExited;
    case 'E':
      // ERROR
      return eStateInvalid;
    default:
      LLDB_LOGF(log, "GDBRemoteClientBase::%s () unrecognized async packet",
                __FUNCTION__);
      return eStateInvalid;
    case 'O': {
      std::string inferior_stdout;
      response.GetHexByteString(inferior_stdout);
      delegate.HandleAsyncStdout(inferior_stdout);
      break;
    }
    case 'A':
      delegate.HandleAsyncMisc(
          llvm::StringRef(response.GetStringRef()).substr(1));
      break;
    case 'J':
      delegate.HandleAsyncStructuredDataPacket(response.GetStringRef());
      break;
    case 'T':
    case 'S':
      // Do this with the continue lock held.
      const bool should_stop = ShouldStop(signals, response);
      response.SetFilePos(0);

      // The packet we should resume with. In the future we should check our
      // thread list and "do the right thing" for new threads that show up
      // while we stop and run async packets. Setting the packet to 'c' to
      // continue all threads is the right thing to do 99.99% of the time
      // because if a thread was single stepping, and we sent an interrupt, we
      // will notice above that we didn't stop due to an interrupt but stopped
      // due to stepping and we would _not_ continue. This packet may get
      // modified by the async actions (e.g. to send a signal).
      m_continue_packet = 'c';
      cont_lock.unlock();

      delegate.HandleStopReply();
      if (should_stop)
        return eStateStopped;

      switch (cont_lock.lock()) {
      case ContinueLock::LockResult::Success:
        break;
      case ContinueLock::LockResult::Failed:
        return eStateInvalid;
      case ContinueLock::LockResult::Cancelled:
        return eStateStopped;
      }
      OnRunPacketSent(false);
      break;
    }
  }
}

bool GDBRemoteClientBase::SendAsyncSignal(int signo) {
  Lock lock(*this, true);
  if (!lock || !lock.DidInterrupt())
    return false;

  m_continue_packet = 'C';
  m_continue_packet += llvm::hexdigit((signo / 16) % 16);
  m_continue_packet += llvm::hexdigit(signo % 16);
  return true;
}

bool GDBRemoteClientBase::Interrupt() {
  Lock lock(*this, true);
  if (!lock.DidInterrupt())
    return false;
  m_should_stop = true;
  return true;
}
GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndWaitForResponse(
    llvm::StringRef payload, StringExtractorGDBRemote &response,
    bool send_async) {
  Lock lock(*this, send_async);
  if (!lock) {
    if (Log *log =
            ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
      LLDB_LOGF(log,
                "GDBRemoteClientBase::%s failed to get mutex, not sending "
                "packet '%.*s' (send_async=%d)",
                __FUNCTION__, int(payload.size()), payload.data(), send_async);
    return PacketResult::ErrorSendFailed;
  }

  return SendPacketAndWaitForResponseNoLock(payload, response);
}

GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndReceiveResponseWithOutputSupport(
    llvm::StringRef payload, StringExtractorGDBRemote &response,
    bool send_async,
    llvm::function_ref<void(llvm::StringRef)> output_callback) {
  Lock lock(*this, send_async);
  if (!lock) {
    if (Log *log =
            ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS))
      LLDB_LOGF(log,
                "GDBRemoteClientBase::%s failed to get mutex, not sending "
                "packet '%.*s' (send_async=%d)",
                __FUNCTION__, int(payload.size()), payload.data(), send_async);
    return PacketResult::ErrorSendFailed;
  }

  PacketResult packet_result = SendPacketNoLock(payload);
  if (packet_result != PacketResult::Success)
    return packet_result;

  return ReadPacketWithOutputSupport(response, GetPacketTimeout(), true,
                                     output_callback);
}

GDBRemoteCommunication::PacketResult
GDBRemoteClientBase::SendPacketAndWaitForResponseNoLock(
    llvm::StringRef payload, StringExtractorGDBRemote &response) {
  PacketResult packet_result = SendPacketNoLock(payload);
  if (packet_result != PacketResult::Success)
    return packet_result;

  const size_t max_response_retries = 3;
  for (size_t i = 0; i < max_response_retries; ++i) {
    packet_result = ReadPacket(response, GetPacketTimeout(), true);
    // Make sure we received a response
    if (packet_result != PacketResult::Success)
      return packet_result;
    // Make sure our response is valid for the payload that was sent
    if (response.ValidateResponse())
      return packet_result;
    // Response says it wasn't valid
    Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS);
    LLDB_LOGF(
        log,
        "error: packet with payload \"%.*s\" got invalid response \"%s\": %s",
        int(payload.size()), payload.data(), response.GetStringRef().data(),
        (i == (max_response_retries - 1))
            ? "using invalid response and giving up"
            : "ignoring response and waiting for another");
  }
  return packet_result;
}

bool GDBRemoteClientBase::SendvContPacket(llvm::StringRef payload,
                                          StringExtractorGDBRemote &response) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
  LLDB_LOGF(log, "GDBRemoteCommunicationClient::%s ()", __FUNCTION__);

  // we want to lock down packet sending while we continue
  Lock lock(*this, true);

  LLDB_LOGF(log,
            "GDBRemoteCommunicationClient::%s () sending vCont packet: %.*s",
            __FUNCTION__, int(payload.size()), payload.data());

  if (SendPacketNoLock(payload) != PacketResult::Success)
    return false;

  OnRunPacketSent(true);

  // wait for the response to the vCont
  if (ReadPacket(response, llvm::None, false) == PacketResult::Success) {
    if (response.IsOKResponse())
      return true;
  }

  return false;
}
bool GDBRemoteClientBase::ShouldStop(const UnixSignals &signals,
                                     StringExtractorGDBRemote &response) {
  std::lock_guard<std::mutex> lock(m_mutex);

  if (m_async_count == 0)
    return true; // We were not interrupted. The process stopped on its own.

  // Older debugserver stubs (before April 2016) can return two stop-reply
  // packets in response to a ^C packet. Additionally, all debugservers still
  // return two stop replies if the inferior stops due to some other reason
  // before the remote stub manages to interrupt it. We need to wait for this
  // additional packet to make sure the packet sequence does not get skewed.
  StringExtractorGDBRemote extra_stop_reply_packet;
  ReadPacket(extra_stop_reply_packet, milliseconds(100), false);

  // Interrupting is typically done using SIGSTOP or SIGINT, so if the process
  // stops with some other signal, we definitely want to stop.
  const uint8_t signo = response.GetHexU8(UINT8_MAX);
  if (signo != signals.GetSignalNumberFromName("SIGSTOP") &&
      signo != signals.GetSignalNumberFromName("SIGINT"))
    return true;

  // We probably only stopped to perform some async processing, so continue
  // after that is done.
  // TODO: This is not 100% correct, as the process may have been stopped with
  // SIGINT or SIGSTOP that was not caused by us (e.g. raise(SIGINT)). This will
  // normally cause a stop, but if it's done concurrently with a async
  // interrupt, that stop will get eaten (llvm.org/pr20231).
  return false;
}

void GDBRemoteClientBase::OnRunPacketSent(bool first) {
  if (first)
    BroadcastEvent(eBroadcastBitRunPacketSent, nullptr);
}

///////////////////////////////////////
// GDBRemoteClientBase::ContinueLock //
///////////////////////////////////////

GDBRemoteClientBase::ContinueLock::ContinueLock(GDBRemoteClientBase &comm)
    : m_comm(comm), m_acquired(false) {
  lock();
}

GDBRemoteClientBase::ContinueLock::~ContinueLock() {
  if (m_acquired)
    unlock();
}

void GDBRemoteClientBase::ContinueLock::unlock() {
  lldbassert(m_acquired);
  {
    std::unique_lock<std::mutex> lock(m_comm.m_mutex);
    m_comm.m_is_running = false;
  }
  m_comm.m_cv.notify_all();
  m_acquired = false;
}

GDBRemoteClientBase::ContinueLock::LockResult
GDBRemoteClientBase::ContinueLock::lock() {
  Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS);
  LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() resuming with %s",
            __FUNCTION__, m_comm.m_continue_packet.c_str());

  lldbassert(!m_acquired);
  std::unique_lock<std::mutex> lock(m_comm.m_mutex);
  m_comm.m_cv.wait(lock, [this] { return m_comm.m_async_count == 0; });
  if (m_comm.m_should_stop) {
    m_comm.m_should_stop = false;
    LLDB_LOGF(log, "GDBRemoteClientBase::ContinueLock::%s() cancelled",
              __FUNCTION__);
    return LockResult::Cancelled;
  }
  if (m_comm.SendPacketNoLock(m_comm.m_continue_packet) !=
      PacketResult::Success)
    return LockResult::Failed;

  lldbassert(!m_comm.m_is_running);
  m_comm.m_is_running = true;
  m_acquired = true;
  return LockResult::Success;
}

///////////////////////////////
// GDBRemoteClientBase::Lock //
///////////////////////////////

GDBRemoteClientBase::Lock::Lock(GDBRemoteClientBase &comm, bool interrupt)
    : m_async_lock(comm.m_async_mutex, std::defer_lock), m_comm(comm),
      m_acquired(false), m_did_interrupt(false) {
  SyncWithContinueThread(interrupt);
  if (m_acquired)
    m_async_lock.lock();
}

void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
  std::unique_lock<std::mutex> lock(m_comm.m_mutex);
  if (m_comm.m_is_running && !interrupt)
    return; // We were asked to avoid interrupting the sender. Lock is not
            // acquired.

  ++m_comm.m_async_count;
  if (m_comm.m_is_running) {
    if (m_comm.m_async_count == 1) {
      // The sender has sent the continue packet and we are the first async
      // packet. Let's interrupt it.
      const char ctrl_c = '\x03';
      ConnectionStatus status = eConnectionStatusSuccess;
      size_t bytes_written = m_comm.Write(&ctrl_c, 1, status, nullptr);
      if (bytes_written == 0) {
        --m_comm.m_async_count;
        LLDB_LOGF(log, "GDBRemoteClientBase::Lock::Lock failed to send "
                       "interrupt packet");
        return;
      }
      if (log)
        log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03");
      m_comm.m_interrupt_time = steady_clock::now();
    }
    m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; });
    m_did_interrupt = true;
  }
  m_acquired = true;
}

GDBRemoteClientBase::Lock::~Lock() {
  if (!m_acquired)
    return;
  {
    std::unique_lock<std::mutex> lock(m_comm.m_mutex);
    --m_comm.m_async_count;
  }
  m_comm.m_cv.notify_one();
}
