//===-- GDBRemoteCommunicationServer.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 <cerrno>

#include "lldb/Host/Config.h"

#include "GDBRemoteCommunicationServer.h"

#include "ProcessGDBRemoteLog.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractorGDBRemote.h"
#include "lldb/Utility/UnimplementedError.h"
#include "llvm/Support/JSON.h"
#include <cstring>

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::process_gdb_remote;
using namespace llvm;

GDBRemoteCommunicationServer::GDBRemoteCommunicationServer()
    : GDBRemoteCommunication(), m_exit_now(false) {
  RegisterPacketHandler(
      StringExtractorGDBRemote::eServerPacketType_QEnableErrorStrings,
      [this](StringExtractorGDBRemote packet, Status &error, bool &interrupt,
             bool &quit) { return this->Handle_QErrorStringEnable(packet); });
}

GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() = default;

void GDBRemoteCommunicationServer::RegisterPacketHandler(
    StringExtractorGDBRemote::ServerPacketType packet_type,
    PacketHandler handler) {
  m_packet_handlers[packet_type] = std::move(handler);
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::GetPacketAndSendResponse(
    Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
  StringExtractorGDBRemote packet;

  PacketResult packet_result = ReadPacket(packet, timeout, false);
  if (packet_result == PacketResult::Success) {
    const StringExtractorGDBRemote::ServerPacketType packet_type =
        packet.GetServerPacketType();
    switch (packet_type) {
    case StringExtractorGDBRemote::eServerPacketType_nack:
    case StringExtractorGDBRemote::eServerPacketType_ack:
      break;

    case StringExtractorGDBRemote::eServerPacketType_invalid:
      error = Status::FromErrorString("invalid packet");
      quit = true;
      break;

    case StringExtractorGDBRemote::eServerPacketType_unimplemented:
      packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
      break;

    default:
      auto handler_it = m_packet_handlers.find(packet_type);
      if (handler_it == m_packet_handlers.end())
        packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
      else
        packet_result = handler_it->second(packet, error, interrupt, quit);
      break;
    }
  } else {
    if (!IsConnected()) {
      error = Status::FromErrorString("lost connection");
      quit = true;
    } else {
      error = Status::FromErrorString("timeout");
    }
  }

  // Check if anything occurred that would force us to want to exit.
  if (m_exit_now)
    quit = true;

  return packet_result;
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendUnimplementedResponse(const char *) {
  // TODO: Log the packet we aren't handling...
  return SendPacketNoLock("");
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendErrorResponse(uint8_t err) {
  char packet[16];
  int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
  assert(packet_len < (int)sizeof(packet));
  return SendPacketNoLock(llvm::StringRef(packet, packet_len));
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendErrorResponse(const Status &error) {
  uint8_t code = error.GetType() == eErrorTypePOSIX ? error.GetError() : 0xff;
  if (m_send_error_strings) {
    lldb_private::StreamString packet;
    packet.Printf("E%2.2x;", code);
    packet.PutStringAsRawHex8(error.AsCString());
    return SendPacketNoLock(packet.GetString());
  }
  return SendErrorResponse(code);
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendErrorResponse(llvm::Error error) {
  assert(error);
  std::unique_ptr<llvm::ErrorInfoBase> EIB;
  std::unique_ptr<UnimplementedError> UE;
  llvm::handleAllErrors(
      std::move(error),
      [&](std::unique_ptr<UnimplementedError> E) { UE = std::move(E); },
      [&](std::unique_ptr<llvm::ErrorInfoBase> E) { EIB = std::move(E); });

  if (EIB)
    return SendErrorResponse(Status::FromError(llvm::Error(std::move(EIB))));
  return SendUnimplementedResponse("");
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QErrorStringEnable(
    StringExtractorGDBRemote &packet) {
  m_send_error_strings = true;
  return SendOKResponse();
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendIllFormedResponse(
    const StringExtractorGDBRemote &failed_packet, const char *message) {
  Log *log = GetLog(GDBRLog::Packets);
  LLDB_LOGF(log, "GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
            __FUNCTION__, failed_packet.GetStringRef().data(),
            message ? message : "");
  return SendErrorResponse(0x03);
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendOKResponse() {
  return SendPacketNoLock("OK");
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) {
  std::string json_string;
  raw_string_ostream os(json_string);
  os << value;
  StreamGDBRemote escaped_response;
  escaped_response.PutEscapedBytes(json_string.c_str(), json_string.size());
  return SendPacketNoLock(escaped_response.GetString());
}

GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendJSONResponse(Expected<json::Value> value) {
  if (!value)
    return SendErrorResponse(value.takeError());
  return SendJSONResponse(*value);
}
