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

// Other libraries and framework includes
#include "lldb/Core/StreamFile.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Log.h"

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

GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size)
    : m_packets(), m_curr_idx(0), m_total_packet_count(0),
      m_dumped_to_log(false) {
  if (size)
    m_packets.resize(size);
}

GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {}

void GDBRemoteCommunicationHistory::AddPacket(char packet_char,
                                              GDBRemotePacket::Type type,
                                              uint32_t bytes_transmitted) {
  const size_t size = m_packets.size();
  if (size == 0)
    return;

  const uint32_t idx = GetNextIndex();
  m_packets[idx].packet.data.assign(1, packet_char);
  m_packets[idx].type = type;
  m_packets[idx].bytes_transmitted = bytes_transmitted;
  m_packets[idx].packet_idx = m_total_packet_count;
  m_packets[idx].tid = llvm::get_threadid();
  if (m_recorder)
    m_recorder->Record(m_packets[idx]);
}

void GDBRemoteCommunicationHistory::AddPacket(const std::string &src,
                                              uint32_t src_len,
                                              GDBRemotePacket::Type type,
                                              uint32_t bytes_transmitted) {
  const size_t size = m_packets.size();
  if (size == 0)
    return;

  const uint32_t idx = GetNextIndex();
  m_packets[idx].packet.data.assign(src, 0, src_len);
  m_packets[idx].type = type;
  m_packets[idx].bytes_transmitted = bytes_transmitted;
  m_packets[idx].packet_idx = m_total_packet_count;
  m_packets[idx].tid = llvm::get_threadid();
  if (m_recorder)
    m_recorder->Record(m_packets[idx]);
}

void GDBRemoteCommunicationHistory::Dump(Stream &strm) const {
  const uint32_t size = GetNumPacketsInHistory();
  const uint32_t first_idx = GetFirstSavedPacketIndex();
  const uint32_t stop_idx = m_curr_idx + size;
  for (uint32_t i = first_idx; i < stop_idx; ++i) {
    const uint32_t idx = NormalizeIndex(i);
    const GDBRemotePacket &entry = m_packets[idx];
    if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
        entry.packet.data.empty())
      break;
    strm.Printf("history[%u] ", entry.packet_idx);
    entry.Dump(strm);
  }
}

void GDBRemoteCommunicationHistory::Dump(Log *log) const {
  if (!log || m_dumped_to_log)
    return;

  m_dumped_to_log = true;
  const uint32_t size = GetNumPacketsInHistory();
  const uint32_t first_idx = GetFirstSavedPacketIndex();
  const uint32_t stop_idx = m_curr_idx + size;
  for (uint32_t i = first_idx; i < stop_idx; ++i) {
    const uint32_t idx = NormalizeIndex(i);
    const GDBRemotePacket &entry = m_packets[idx];
    if (entry.type == GDBRemotePacket::ePacketTypeInvalid ||
        entry.packet.data.empty())
      break;
    LLDB_LOGF(log, "history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
              entry.packet_idx, entry.tid, entry.bytes_transmitted,
              (entry.type == GDBRemotePacket::ePacketTypeSend) ? "send"
                                                               : "read",
              entry.packet.data.c_str());
  }
}

