//===-- GDBRemote.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/Utility/GDBRemote.h"

#include "lldb/Utility/Flags.h"
#include "lldb/Utility/Stream.h"

#include <stdio.h>

using namespace lldb;
using namespace lldb_private::repro;
using namespace lldb_private;
using namespace llvm;

StreamGDBRemote::StreamGDBRemote() : StreamString() {}

StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size,
                                 ByteOrder byte_order)
    : StreamString(flags, addr_size, byte_order) {}

StreamGDBRemote::~StreamGDBRemote() {}

int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
  int bytes_written = 0;
  const uint8_t *src = static_cast<const uint8_t *>(s);
  bool binary_is_set = m_flags.Test(eBinary);
  m_flags.Clear(eBinary);
  while (src_len) {
    uint8_t byte = *src;
    src++;
    src_len--;
    if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) {
      bytes_written += PutChar(0x7d);
      byte ^= 0x20;
    }
    bytes_written += PutChar(byte);
  };
  if (binary_is_set)
    m_flags.Set(eBinary);
  return bytes_written;
}

llvm::StringRef GDBRemotePacket::GetTypeStr() const {
  switch (type) {
  case GDBRemotePacket::ePacketTypeSend:
    return "send";
  case GDBRemotePacket::ePacketTypeRecv:
    return "read";
  case GDBRemotePacket::ePacketTypeInvalid:
    return "invalid";
  }
  llvm_unreachable("All enum cases should be handled");
}

void GDBRemotePacket::Dump(Stream &strm) const {
  strm.Printf("tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", tid,
              bytes_transmitted, GetTypeStr().data(), packet.data.c_str());
}

void yaml::ScalarEnumerationTraits<GDBRemotePacket::Type>::enumeration(
    IO &io, GDBRemotePacket::Type &value) {
  io.enumCase(value, "Invalid", GDBRemotePacket::ePacketTypeInvalid);
  io.enumCase(value, "Send", GDBRemotePacket::ePacketTypeSend);
  io.enumCase(value, "Recv", GDBRemotePacket::ePacketTypeRecv);
}

void yaml::ScalarTraits<GDBRemotePacket::BinaryData>::output(
    const GDBRemotePacket::BinaryData &Val, void *, raw_ostream &Out) {
  Out << toHex(Val.data);
}

StringRef yaml::ScalarTraits<GDBRemotePacket::BinaryData>::input(
    StringRef Scalar, void *, GDBRemotePacket::BinaryData &Val) {
  Val.data = fromHex(Scalar);
  return {};
}

void yaml::MappingTraits<GDBRemotePacket>::mapping(IO &io,
                                                   GDBRemotePacket &Packet) {
  io.mapRequired("packet", Packet.packet);
  io.mapRequired("type", Packet.type);
  io.mapRequired("bytes", Packet.bytes_transmitted);
  io.mapRequired("index", Packet.packet_idx);
  io.mapRequired("tid", Packet.tid);
}

StringRef
yaml::MappingTraits<GDBRemotePacket>::validate(IO &io,
                                               GDBRemotePacket &Packet) {
  return {};
}

void GDBRemoteProvider::Keep() {
  std::vector<std::string> files;
  for (auto &recorder : m_packet_recorders) {
    files.push_back(recorder->GetFilename().GetPath());
  }

  FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file);
  std::error_code ec;
  llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text);
  if (ec)
    return;
  yaml::Output yout(os);
  yout << files;
}

void GDBRemoteProvider::Discard() { m_packet_recorders.clear(); }

llvm::Expected<std::unique_ptr<PacketRecorder>>
PacketRecorder::Create(const FileSpec &filename) {
  std::error_code ec;
  auto recorder = std::make_unique<PacketRecorder>(std::move(filename), ec);
  if (ec)
    return llvm::errorCodeToError(ec);
  return std::move(recorder);
}

PacketRecorder *GDBRemoteProvider::GetNewPacketRecorder() {
  std::size_t i = m_packet_recorders.size() + 1;
  std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") +
                          llvm::Twine(i) + llvm::Twine(".yaml"))
                             .str();
  auto recorder_or_error =
      PacketRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename));
  if (!recorder_or_error) {
    llvm::consumeError(recorder_or_error.takeError());
    return nullptr;
  }

  m_packet_recorders.push_back(std::move(*recorder_or_error));
  return m_packet_recorders.back().get();
}

void PacketRecorder::Record(const GDBRemotePacket &packet) {
  if (!m_record)
    return;
  yaml::Output yout(m_os);
  yout << const_cast<GDBRemotePacket &>(packet);
  m_os.flush();
}

llvm::raw_ostream *GDBRemoteProvider::GetHistoryStream() {
  FileSpec history_file = GetRoot().CopyByAppendingPathComponent(Info::file);

  std::error_code EC;
  m_stream_up = std::make_unique<raw_fd_ostream>(history_file.GetPath(), EC,
                                                 sys::fs::OpenFlags::OF_Text);
  return m_stream_up.get();
}

char GDBRemoteProvider::ID = 0;
const char *GDBRemoteProvider::Info::file = "gdb-remote.yaml";
const char *GDBRemoteProvider::Info::name = "gdb-remote";
