//===-- TraceDumper.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/Target/TraceDumper.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;
using namespace llvm;

/// \return
///   The given string or \b std::nullopt if it's empty.
static std::optional<const char *> ToOptionalString(const char *s) {
  if (!s)
    return std::nullopt;
  return s;
}

static const char *GetModuleName(const SymbolContext &sc) {
  if (!sc.module_sp)
    return nullptr;
  return sc.module_sp->GetFileSpec().GetFilename().AsCString();
}

/// \return
///   The module name (basename if the module is a file, or the actual name if
///   it's a virtual module), or \b nullptr if no name nor module was found.
static const char *GetModuleName(const TraceDumper::TraceItem &item) {
  if (!item.symbol_info)
    return nullptr;
  return GetModuleName(item.symbol_info->sc);
}

// This custom LineEntry validator is neded because some line_entries have
// 0 as line, which is meaningless. Notice that LineEntry::IsValid only
// checks that line is not LLDB_INVALID_LINE_NUMBER, i.e. UINT32_MAX.
static bool IsLineEntryValid(const LineEntry &line_entry) {
  return line_entry.IsValid() && line_entry.line > 0;
}

/// \return
///     \b true if the provided line entries match line, column and source file.
///     This function assumes that the line entries are valid.
static bool FileLineAndColumnMatches(const LineEntry &a, const LineEntry &b) {
  if (a.line != b.line)
    return false;
  if (a.column != b.column)
    return false;
  return a.file == b.file;
}

/// Compare the symbol contexts of the provided \a SymbolInfo
/// objects.
///
/// \return
///     \a true if both instructions belong to the same scope level analized
///     in the following order:
///       - module
///       - symbol
///       - function
///       - inlined function
///       - source line info
static bool
IsSameInstructionSymbolContext(const TraceDumper::SymbolInfo &prev_insn,
                               const TraceDumper::SymbolInfo &insn,
                               bool check_source_line_info = true) {
  // module checks
  if (insn.sc.module_sp != prev_insn.sc.module_sp)
    return false;

  // symbol checks
  if (insn.sc.symbol != prev_insn.sc.symbol)
    return false;

  // function checks
  if (!insn.sc.function && !prev_insn.sc.function)
    return true; // This means two dangling instruction in the same module. We
                 // can assume they are part of the same unnamed symbol
  else if (insn.sc.function != prev_insn.sc.function)
    return false;

  Block *inline_block_a =
      insn.sc.block ? insn.sc.block->GetContainingInlinedBlock() : nullptr;
  Block *inline_block_b = prev_insn.sc.block
                              ? prev_insn.sc.block->GetContainingInlinedBlock()
                              : nullptr;
  if (inline_block_a != inline_block_b)
    return false;

  // line entry checks
  if (!check_source_line_info)
    return true;

  const bool curr_line_valid = IsLineEntryValid(insn.sc.line_entry);
  const bool prev_line_valid = IsLineEntryValid(prev_insn.sc.line_entry);
  if (curr_line_valid && prev_line_valid)
    return FileLineAndColumnMatches(insn.sc.line_entry,
                                    prev_insn.sc.line_entry);
  return curr_line_valid == prev_line_valid;
}

class OutputWriterCLI : public TraceDumper::OutputWriter {
public:
  OutputWriterCLI(Stream &s, const TraceDumperOptions &options, Thread &thread)
      : m_s(s), m_options(options) {
    m_s.Format("thread #{0}: tid = {1}\n", thread.GetIndexID(), thread.GetID());
  };

  void NoMoreData() override { m_s << "    no more data\n"; }

  void FunctionCallForest(
      const std::vector<TraceDumper::FunctionCallUP> &forest) override {
    for (size_t i = 0; i < forest.size(); i++) {
      m_s.Format("\n[call tree #{0}]\n", i);
      DumpFunctionCallTree(*forest[i]);
    }
  }

  void TraceItem(const TraceDumper::TraceItem &item) override {
    if (item.symbol_info) {
      if (!item.prev_symbol_info ||
          !IsSameInstructionSymbolContext(*item.prev_symbol_info,
                                          *item.symbol_info)) {
        m_s << "  ";
        const char *module_name = GetModuleName(item);
        if (!module_name)
          m_s << "(none)";
        else if (!item.symbol_info->sc.function && !item.symbol_info->sc.symbol)
          m_s.Format("{0}`(none)", module_name);
        else
          item.symbol_info->sc.DumpStopContext(
              &m_s, item.symbol_info->exe_ctx.GetTargetPtr(),
              item.symbol_info->address,
              /*show_fullpaths=*/false,
              /*show_module=*/true, /*show_inlined_frames=*/false,
              /*show_function_arguments=*/true,
              /*show_function_name=*/true);
        m_s << "\n";
      }
    }

    if (item.error && !m_was_prev_instruction_an_error)
      m_s << "    ...missing instructions\n";

    m_s.Format("    {0}: ", item.id);

    if (m_options.show_timestamps) {
      m_s.Format("[{0}] ", item.timestamp
                               ? formatv("{0:3} ns", *item.timestamp).str()
                               : "unavailable");
    }

    if (item.event) {
      m_s << "(event) " << TraceCursor::EventKindToString(*item.event);
      switch (*item.event) {
      case eTraceEventCPUChanged:
        m_s.Format(" [new CPU={0}]",
                   item.cpu_id ? std::to_string(*item.cpu_id) : "unavailable");
        break;
      case eTraceEventHWClockTick:
        m_s.Format(" [{0}]", item.hw_clock ? std::to_string(*item.hw_clock)
                                           : "unavailable");
        break;
      case eTraceEventDisabledHW:
      case eTraceEventDisabledSW:
        break;
      case eTraceEventSyncPoint:
        m_s.Format(" [{0}]", item.sync_point_metadata);
        break;
      }
    } else if (item.error) {
      m_s << "(error) " << *item.error;
    } else {
      m_s.Format("{0:x+16}", item.load_address);
      if (item.symbol_info && item.symbol_info->instruction) {
        m_s << "    ";
        item.symbol_info->instruction->Dump(
            &m_s, /*max_opcode_byte_size=*/0,
            /*show_address=*/false,
            /*show_bytes=*/false, m_options.show_control_flow_kind,
            &item.symbol_info->exe_ctx, &item.symbol_info->sc,
            /*prev_sym_ctx=*/nullptr,
            /*disassembly_addr_format=*/nullptr,
            /*max_address_text_size=*/0);
      }
    }

    m_was_prev_instruction_an_error = (bool)item.error;
    m_s << "\n";
  }

private:
  void
  DumpSegmentContext(const TraceDumper::FunctionCall::TracedSegment &segment) {
    if (segment.GetOwningCall().IsError()) {
      m_s << "<tracing errors>";
      return;
    }

    const SymbolContext &first_sc = segment.GetFirstInstructionSymbolInfo().sc;
    first_sc.DumpStopContext(
        &m_s, segment.GetFirstInstructionSymbolInfo().exe_ctx.GetTargetPtr(),
        segment.GetFirstInstructionSymbolInfo().address,
        /*show_fullpaths=*/false,
        /*show_module=*/true, /*show_inlined_frames=*/false,
        /*show_function_arguments=*/true,
        /*show_function_name=*/true);
    m_s << " to ";
    const SymbolContext &last_sc = segment.GetLastInstructionSymbolInfo().sc;
    if (IsLineEntryValid(first_sc.line_entry) &&
        IsLineEntryValid(last_sc.line_entry)) {
      m_s.Format("{0}:{1}", last_sc.line_entry.line, last_sc.line_entry.column);
    } else {
      last_sc.DumpStopContext(
          &m_s, segment.GetFirstInstructionSymbolInfo().exe_ctx.GetTargetPtr(),
          segment.GetLastInstructionSymbolInfo().address,
          /*show_fullpaths=*/false,
          /*show_module=*/false, /*show_inlined_frames=*/false,
          /*show_function_arguments=*/false,
          /*show_function_name=*/false);
    }
  }

  void DumpUntracedContext(const TraceDumper::FunctionCall &function_call) {
    if (function_call.IsError()) {
      m_s << "tracing error";
    }
    const SymbolContext &sc = function_call.GetSymbolInfo().sc;

    const char *module_name = GetModuleName(sc);
    if (!module_name)
      m_s << "(none)";
    else if (!sc.function && !sc.symbol)
      m_s << module_name << "`(none)";
    else
      m_s << module_name << "`" << sc.GetFunctionName().AsCString();
  }

  void DumpFunctionCallTree(const TraceDumper::FunctionCall &function_call) {
    if (function_call.GetUntracedPrefixSegment()) {
      m_s.Indent();
      DumpUntracedContext(function_call);
      m_s << "\n";

      m_s.IndentMore();
      DumpFunctionCallTree(function_call.GetUntracedPrefixSegment()->GetNestedCall());
      m_s.IndentLess();
    }

    for (const TraceDumper::FunctionCall::TracedSegment &segment :
         function_call.GetTracedSegments()) {
      m_s.Indent();
      DumpSegmentContext(segment);
      m_s.Format("  [{0}, {1}]\n", segment.GetFirstInstructionID(),
                 segment.GetLastInstructionID());

      segment.IfNestedCall([&](const TraceDumper::FunctionCall &nested_call) {
        m_s.IndentMore();
        DumpFunctionCallTree(nested_call);
        m_s.IndentLess();
      });
    }
  }

  Stream &m_s;
  TraceDumperOptions m_options;
  bool m_was_prev_instruction_an_error = false;
};

class OutputWriterJSON : public TraceDumper::OutputWriter {
  /* schema:
    error_message: string
    | {
      "event": string,
      "id": decimal,
      "tsc"?: string decimal,
      "cpuId"? decimal,
    } | {
      "error": string,
      "id": decimal,
      "tsc"?: string decimal,
    | {
      "loadAddress": string decimal,
      "id": decimal,
      "hwClock"?: string decimal,
      "syncPointMetadata"?: string,
      "timestamp_ns"?: string decimal,
      "module"?: string,
      "symbol"?: string,
      "line"?: decimal,
      "column"?: decimal,
      "source"?: string,
      "mnemonic"?: string,
      "controlFlowKind"?: string,
    }
  */
public:
  OutputWriterJSON(Stream &s, const TraceDumperOptions &options)
      : m_s(s), m_options(options),
        m_j(m_s.AsRawOstream(),
            /*IndentSize=*/options.pretty_print_json ? 2 : 0) {
    m_j.arrayBegin();
  };

  ~OutputWriterJSON() { m_j.arrayEnd(); }

  void FunctionCallForest(
      const std::vector<TraceDumper::FunctionCallUP> &forest) override {
    for (size_t i = 0; i < forest.size(); i++) {
      m_j.object([&] { DumpFunctionCallTree(*forest[i]); });
    }
  }

  void DumpFunctionCallTree(const TraceDumper::FunctionCall &function_call) {
    if (function_call.GetUntracedPrefixSegment()) {
      m_j.attributeObject("untracedPrefixSegment", [&] {
        m_j.attributeObject("nestedCall", [&] {
          DumpFunctionCallTree(
              function_call.GetUntracedPrefixSegment()->GetNestedCall());
        });
      });
    }

    if (!function_call.GetTracedSegments().empty()) {
      m_j.attributeArray("tracedSegments", [&] {
        for (const TraceDumper::FunctionCall::TracedSegment &segment :
             function_call.GetTracedSegments()) {
          m_j.object([&] {
            m_j.attribute("firstInstructionId",
                          std::to_string(segment.GetFirstInstructionID()));
            m_j.attribute("lastInstructionId",
                          std::to_string(segment.GetLastInstructionID()));
            segment.IfNestedCall(
                [&](const TraceDumper::FunctionCall &nested_call) {
                  m_j.attributeObject(
                      "nestedCall", [&] { DumpFunctionCallTree(nested_call); });
                });
          });
        }
      });
    }
  }

  void DumpEvent(const TraceDumper::TraceItem &item) {
    m_j.attribute("event", TraceCursor::EventKindToString(*item.event));
    switch (*item.event) {
    case eTraceEventCPUChanged:
      m_j.attribute("cpuId", item.cpu_id);
      break;
    case eTraceEventHWClockTick:
      m_j.attribute("hwClock", item.hw_clock);
      break;
    case eTraceEventDisabledHW:
    case eTraceEventDisabledSW:
      break;
    case eTraceEventSyncPoint:
      m_j.attribute("syncPointMetadata", item.sync_point_metadata);
      break;
    }
  }

  void DumpInstruction(const TraceDumper::TraceItem &item) {
    m_j.attribute("loadAddress", formatv("{0:x}", item.load_address));
    if (item.symbol_info) {
      m_j.attribute("module", ToOptionalString(GetModuleName(item)));
      m_j.attribute(
          "symbol",
          ToOptionalString(item.symbol_info->sc.GetFunctionName().AsCString()));

      if (lldb::InstructionSP instruction = item.symbol_info->instruction) {
        ExecutionContext exe_ctx = item.symbol_info->exe_ctx;
        m_j.attribute("mnemonic",
                      ToOptionalString(instruction->GetMnemonic(&exe_ctx)));
        if (m_options.show_control_flow_kind) {
          lldb::InstructionControlFlowKind instruction_control_flow_kind =
              instruction->GetControlFlowKind(&exe_ctx);
          m_j.attribute("controlFlowKind",
                        ToOptionalString(
                            Instruction::GetNameForInstructionControlFlowKind(
                                instruction_control_flow_kind)));
        }
      }

      if (IsLineEntryValid(item.symbol_info->sc.line_entry)) {
        m_j.attribute(
            "source",
            ToOptionalString(
                item.symbol_info->sc.line_entry.file.GetPath().c_str()));
        m_j.attribute("line", item.symbol_info->sc.line_entry.line);
        m_j.attribute("column", item.symbol_info->sc.line_entry.column);
      }
    }
  }

  void TraceItem(const TraceDumper::TraceItem &item) override {
    m_j.object([&] {
      m_j.attribute("id", item.id);
      if (m_options.show_timestamps)
        m_j.attribute("timestamp_ns", item.timestamp
                                          ? std::optional<std::string>(
                                                std::to_string(*item.timestamp))
                                          : std::nullopt);

      if (item.event) {
        DumpEvent(item);
      } else if (item.error) {
        m_j.attribute("error", *item.error);
      } else {
        DumpInstruction(item);
      }
    });
  }

private:
  Stream &m_s;
  TraceDumperOptions m_options;
  json::OStream m_j;
};

static std::unique_ptr<TraceDumper::OutputWriter>
CreateWriter(Stream &s, const TraceDumperOptions &options, Thread &thread) {
  if (options.json)
    return std::unique_ptr<TraceDumper::OutputWriter>(
        new OutputWriterJSON(s, options));
  else
    return std::unique_ptr<TraceDumper::OutputWriter>(
        new OutputWriterCLI(s, options, thread));
}

TraceDumper::TraceDumper(lldb::TraceCursorSP cursor_sp, Stream &s,
                         const TraceDumperOptions &options)
    : m_cursor_sp(std::move(cursor_sp)), m_options(options),
      m_writer_up(CreateWriter(
          s, m_options, *m_cursor_sp->GetExecutionContextRef().GetThreadSP())) {

  if (m_options.id)
    m_cursor_sp->GoToId(*m_options.id);
  else if (m_options.forwards)
    m_cursor_sp->Seek(0, lldb::eTraceCursorSeekTypeBeginning);
  else
    m_cursor_sp->Seek(0, lldb::eTraceCursorSeekTypeEnd);

  m_cursor_sp->SetForwards(m_options.forwards);
  if (m_options.skip) {
    m_cursor_sp->Seek((m_options.forwards ? 1 : -1) * *m_options.skip,
                      lldb::eTraceCursorSeekTypeCurrent);
  }
}

TraceDumper::TraceItem TraceDumper::CreatRawTraceItem() {
  TraceItem item = {};
  item.id = m_cursor_sp->GetId();

  if (m_options.show_timestamps)
    item.timestamp = m_cursor_sp->GetWallClockTime();
  return item;
}

/// Find the symbol context for the given address reusing the previous
/// instruction's symbol context when possible.
static SymbolContext
CalculateSymbolContext(const Address &address,
                       const SymbolContext &prev_symbol_context) {
  lldb_private::AddressRange range;
  if (prev_symbol_context.GetAddressRange(eSymbolContextEverything, 0,
                                          /*inline_block_range*/ true, range) &&
      range.Contains(address))
    return prev_symbol_context;

  SymbolContext sc;
  address.CalculateSymbolContext(&sc, eSymbolContextEverything);
  return sc;
}

/// Find the disassembler for the given address reusing the previous
/// instruction's disassembler when possible.
static std::tuple<DisassemblerSP, InstructionSP>
CalculateDisass(const TraceDumper::SymbolInfo &symbol_info,
                const TraceDumper::SymbolInfo &prev_symbol_info,
                const ExecutionContext &exe_ctx) {
  if (prev_symbol_info.disassembler) {
    if (InstructionSP instruction =
            prev_symbol_info.disassembler->GetInstructionList()
                .GetInstructionAtAddress(symbol_info.address))
      return std::make_tuple(prev_symbol_info.disassembler, instruction);
  }

  if (symbol_info.sc.function) {
    if (DisassemblerSP disassembler =
            symbol_info.sc.function->GetInstructions(exe_ctx, nullptr)) {
      if (InstructionSP instruction =
              disassembler->GetInstructionList().GetInstructionAtAddress(
                  symbol_info.address))
        return std::make_tuple(disassembler, instruction);
    }
  }
  // We fallback to a single instruction disassembler
  Target &target = exe_ctx.GetTargetRef();
  const ArchSpec arch = target.GetArchitecture();
  lldb_private::AddressRange range(symbol_info.address,
                                   arch.GetMaximumOpcodeByteSize());
  DisassemblerSP disassembler =
      Disassembler::DisassembleRange(arch, /*plugin_name*/ nullptr,
                                     /*flavor*/ nullptr, target, range);
  return std::make_tuple(
      disassembler,
      disassembler ? disassembler->GetInstructionList().GetInstructionAtAddress(
                         symbol_info.address)
                   : InstructionSP());
}

static TraceDumper::SymbolInfo
CalculateSymbolInfo(const ExecutionContext &exe_ctx, lldb::addr_t load_address,
                    const TraceDumper::SymbolInfo &prev_symbol_info) {
  TraceDumper::SymbolInfo symbol_info;
  symbol_info.exe_ctx = exe_ctx;
  symbol_info.address.SetLoadAddress(load_address, exe_ctx.GetTargetPtr());
  symbol_info.sc =
      CalculateSymbolContext(symbol_info.address, prev_symbol_info.sc);
  std::tie(symbol_info.disassembler, symbol_info.instruction) =
      CalculateDisass(symbol_info, prev_symbol_info, exe_ctx);
  return symbol_info;
}

std::optional<lldb::user_id_t> TraceDumper::DumpInstructions(size_t count) {
  ThreadSP thread_sp = m_cursor_sp->GetExecutionContextRef().GetThreadSP();

  SymbolInfo prev_symbol_info;
  std::optional<lldb::user_id_t> last_id;

  ExecutionContext exe_ctx;
  thread_sp->GetProcess()->GetTarget().CalculateExecutionContext(exe_ctx);

  for (size_t insn_seen = 0; insn_seen < count && m_cursor_sp->HasValue();
       m_cursor_sp->Next()) {

    last_id = m_cursor_sp->GetId();
    TraceItem item = CreatRawTraceItem();

    if (m_cursor_sp->IsEvent() && m_options.show_events) {
      item.event = m_cursor_sp->GetEventType();
      switch (*item.event) {
      case eTraceEventCPUChanged:
        item.cpu_id = m_cursor_sp->GetCPU();
        break;
      case eTraceEventHWClockTick:
        item.hw_clock = m_cursor_sp->GetHWClock();
        break;
      case eTraceEventDisabledHW:
      case eTraceEventDisabledSW:
        break;
      case eTraceEventSyncPoint:
        item.sync_point_metadata = m_cursor_sp->GetSyncPointMetadata();
        break;
      }
      m_writer_up->TraceItem(item);
    } else if (m_cursor_sp->IsError()) {
      item.error = m_cursor_sp->GetError();
      m_writer_up->TraceItem(item);
    } else if (m_cursor_sp->IsInstruction() && !m_options.only_events) {
      insn_seen++;
      item.load_address = m_cursor_sp->GetLoadAddress();

      if (!m_options.raw) {
        SymbolInfo symbol_info =
            CalculateSymbolInfo(exe_ctx, item.load_address, prev_symbol_info);
        item.prev_symbol_info = prev_symbol_info;
        item.symbol_info = symbol_info;
        prev_symbol_info = symbol_info;
      }
      m_writer_up->TraceItem(item);
    }
  }
  if (!m_cursor_sp->HasValue())
    m_writer_up->NoMoreData();
  return last_id;
}

void TraceDumper::FunctionCall::TracedSegment::AppendInsn(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {
  m_last_insn_id = cursor_sp->GetId();
  m_last_symbol_info = symbol_info;
}

lldb::user_id_t
TraceDumper::FunctionCall::TracedSegment::GetFirstInstructionID() const {
  return m_first_insn_id;
}

lldb::user_id_t
TraceDumper::FunctionCall::TracedSegment::GetLastInstructionID() const {
  return m_last_insn_id;
}

void TraceDumper::FunctionCall::TracedSegment::IfNestedCall(
    std::function<void(const FunctionCall &function_call)> callback) const {
  if (m_nested_call)
    callback(*m_nested_call);
}

const TraceDumper::FunctionCall &
TraceDumper::FunctionCall::TracedSegment::GetOwningCall() const {
  return m_owning_call;
}

TraceDumper::FunctionCall &
TraceDumper::FunctionCall::TracedSegment::CreateNestedCall(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {
  m_nested_call = std::make_unique<FunctionCall>(cursor_sp, symbol_info);
  m_nested_call->SetParentCall(m_owning_call);
  return *m_nested_call;
}

const TraceDumper::SymbolInfo &
TraceDumper::FunctionCall::TracedSegment::GetFirstInstructionSymbolInfo()
    const {
  return m_first_symbol_info;
}

const TraceDumper::SymbolInfo &
TraceDumper::FunctionCall::TracedSegment::GetLastInstructionSymbolInfo() const {
  return m_last_symbol_info;
}

const TraceDumper::FunctionCall &
TraceDumper::FunctionCall::UntracedPrefixSegment::GetNestedCall() const {
  return *m_nested_call;
}

TraceDumper::FunctionCall::FunctionCall(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {
  m_is_error = cursor_sp->IsError();
  AppendSegment(cursor_sp, symbol_info);
}

void TraceDumper::FunctionCall::AppendSegment(
    const TraceCursorSP &cursor_sp,
    const TraceDumper::SymbolInfo &symbol_info) {
  m_traced_segments.emplace_back(cursor_sp, symbol_info, *this);
}

const TraceDumper::SymbolInfo &
TraceDumper::FunctionCall::GetSymbolInfo() const {
  return m_traced_segments.back().GetLastInstructionSymbolInfo();
}

bool TraceDumper::FunctionCall::IsError() const { return m_is_error; }

const std::deque<TraceDumper::FunctionCall::TracedSegment> &
TraceDumper::FunctionCall::GetTracedSegments() const {
  return m_traced_segments;
}

TraceDumper::FunctionCall::TracedSegment &
TraceDumper::FunctionCall::GetLastTracedSegment() {
  return m_traced_segments.back();
}

const std::optional<TraceDumper::FunctionCall::UntracedPrefixSegment> &
TraceDumper::FunctionCall::GetUntracedPrefixSegment() const {
  return m_untraced_prefix_segment;
}

void TraceDumper::FunctionCall::SetUntracedPrefixSegment(
    TraceDumper::FunctionCallUP &&nested_call) {
  m_untraced_prefix_segment.emplace(std::move(nested_call));
}

TraceDumper::FunctionCall *TraceDumper::FunctionCall::GetParentCall() const {
  return m_parent_call;
}

void TraceDumper::FunctionCall::SetParentCall(
    TraceDumper::FunctionCall &parent_call) {
  m_parent_call = &parent_call;
}

/// Given an instruction that happens after a return, find the ancestor function
/// call that owns it. If this ancestor doesn't exist, create a new ancestor and
/// make it the root of the tree.
///
/// \param[in] last_function_call
///   The function call that performs the return.
///
/// \param[in] symbol_info
///   The symbol information of the instruction after the return.
///
/// \param[in] cursor_sp
///   The cursor pointing to the instruction after the return.
///
/// \param[in,out] roots
///   The object owning the roots. It might be modified if a new root needs to
///   be created.
///
/// \return
///   A reference to the function call that owns the new instruction
static TraceDumper::FunctionCall &AppendReturnedInstructionToFunctionCallForest(
    TraceDumper::FunctionCall &last_function_call,
    const TraceDumper::SymbolInfo &symbol_info, const TraceCursorSP &cursor_sp,
    std::vector<TraceDumper::FunctionCallUP> &roots) {

  // We omit the current node because we can't return to itself.
  TraceDumper::FunctionCall *ancestor = last_function_call.GetParentCall();

  for (; ancestor; ancestor = ancestor->GetParentCall()) {
    // This loop traverses the tree until it finds a call that we can return to.
    if (IsSameInstructionSymbolContext(ancestor->GetSymbolInfo(), symbol_info,
                                       /*check_source_line_info=*/false)) {
      // We returned to this symbol, so we are assuming we are returning there
      // Note: If this is not robust enough, we should actually check if we
      // returning to the instruction that follows the last instruction from
      // that call, as that's the behavior of CALL instructions.
      ancestor->AppendSegment(cursor_sp, symbol_info);
      return *ancestor;
    }
  }

  // We didn't find the call we were looking for, so we now create a synthetic
  // one that will contain the new instruction in its first traced segment.
  TraceDumper::FunctionCallUP new_root =
      std::make_unique<TraceDumper::FunctionCall>(cursor_sp, symbol_info);
  // This new root will own the previous root through an untraced prefix segment.
  new_root->SetUntracedPrefixSegment(std::move(roots.back()));
  roots.pop_back();
  // We update the roots container to point to the new root
  roots.emplace_back(std::move(new_root));
  return *roots.back();
}

/// Append an instruction to a function call forest. The new instruction might
/// be appended to the current segment, to a new nest call, or return to an
/// ancestor call.
///
/// \param[in] exe_ctx
///   The exeuction context of the traced thread.
///
/// \param[in] last_function_call
///   The chronologically most recent function call before the new instruction.
///
/// \param[in] prev_symbol_info
///   The symbol information of the previous instruction in the trace.
///
/// \param[in] symbol_info
///   The symbol information of the new instruction.
///
/// \param[in] cursor_sp
///   The cursor pointing to the new instruction.
///
/// \param[in,out] roots
///   The object owning the roots. It might be modified if a new root needs to
///   be created.
///
/// \return
///   A reference to the function call that owns the new instruction.
static TraceDumper::FunctionCall &AppendInstructionToFunctionCallForest(
    const ExecutionContext &exe_ctx,
    TraceDumper::FunctionCall *last_function_call,
    const TraceDumper::SymbolInfo &prev_symbol_info,
    const TraceDumper::SymbolInfo &symbol_info, const TraceCursorSP &cursor_sp,
    std::vector<TraceDumper::FunctionCallUP> &roots) {
  if (!last_function_call || last_function_call->IsError()) {
    // We create a brand new root
    roots.emplace_back(
        std::make_unique<TraceDumper::FunctionCall>(cursor_sp, symbol_info));
    return *roots.back();
  }

  lldb_private::AddressRange range;
  if (symbol_info.sc.GetAddressRange(
          eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol,
          0, /*inline_block_range*/ true, range)) {
    if (range.GetBaseAddress() == symbol_info.address) {
      // Our instruction is the first instruction of a function. This has
      // to be a call. This should also identify if a trampoline or the linker
      // is making a call using a non-CALL instruction.
      return last_function_call->GetLastTracedSegment().CreateNestedCall(
          cursor_sp, symbol_info);
    }
  }
  if (IsSameInstructionSymbolContext(prev_symbol_info, symbol_info,
                                     /*check_source_line_info=*/false)) {
    // We are still in the same function. This can't be a call because otherwise
    // we would be in the first instruction of the symbol.
    last_function_call->GetLastTracedSegment().AppendInsn(cursor_sp,
                                                          symbol_info);
    return *last_function_call;
  }
  // Now we are in a different symbol. Let's see if this is a return or a
  // call
  const InstructionSP &insn = last_function_call->GetLastTracedSegment()
                                  .GetLastInstructionSymbolInfo()
                                  .instruction;
  InstructionControlFlowKind insn_kind =
      insn ? insn->GetControlFlowKind(&exe_ctx)
           : eInstructionControlFlowKindOther;

  switch (insn_kind) {
  case lldb::eInstructionControlFlowKindCall:
  case lldb::eInstructionControlFlowKindFarCall: {
    // This is a regular call
    return last_function_call->GetLastTracedSegment().CreateNestedCall(
        cursor_sp, symbol_info);
  }
  case lldb::eInstructionControlFlowKindFarReturn:
  case lldb::eInstructionControlFlowKindReturn: {
    // We should have caught most trampolines and linker functions earlier, so
    // let's assume this is a regular return.
    return AppendReturnedInstructionToFunctionCallForest(
        *last_function_call, symbol_info, cursor_sp, roots);
  }
  default:
    // we changed symbols not using a call or return and we are not in the
    // beginning of a symbol, so this should be something very artificial
    // or maybe a jump to some label in the middle of it section.

    // We first check if it's a return from an inline method
    if (prev_symbol_info.sc.block &&
        prev_symbol_info.sc.block->GetContainingInlinedBlock()) {
      return AppendReturnedInstructionToFunctionCallForest(
          *last_function_call, symbol_info, cursor_sp, roots);
    }
    // Now We assume it's a call. We should revisit this in the future.
    // Ideally we should be able to decide whether to create a new tree,
    // or go deeper or higher in the stack.
    return last_function_call->GetLastTracedSegment().CreateNestedCall(
        cursor_sp, symbol_info);
  }
}

/// Append an error to a function call forest. The new error might be appended
/// to the current segment if it contains errors or will create a new root.
///
/// \param[in] last_function_call
///   The chronologically most recent function call before the new error.
///
/// \param[in] cursor_sp
///   The cursor pointing to the new error.
///
/// \param[in,out] roots
///   The object owning the roots. It might be modified if a new root needs to
///   be created.
///
/// \return
///   A reference to the function call that owns the new error.
TraceDumper::FunctionCall &AppendErrorToFunctionCallForest(
    TraceDumper::FunctionCall *last_function_call, TraceCursorSP &cursor_sp,
    std::vector<TraceDumper::FunctionCallUP> &roots) {
  if (last_function_call && last_function_call->IsError()) {
    last_function_call->GetLastTracedSegment().AppendInsn(
        cursor_sp, TraceDumper::SymbolInfo{});
    return *last_function_call;
  } else {
    roots.emplace_back(std::make_unique<TraceDumper::FunctionCall>(
        cursor_sp, TraceDumper::SymbolInfo{}));
    return *roots.back();
  }
}

static std::vector<TraceDumper::FunctionCallUP>
CreateFunctionCallForest(TraceCursorSP &cursor_sp,
                         const ExecutionContext &exe_ctx) {

  std::vector<TraceDumper::FunctionCallUP> roots;
  TraceDumper::SymbolInfo prev_symbol_info;

  TraceDumper::FunctionCall *last_function_call = nullptr;

  for (; cursor_sp->HasValue(); cursor_sp->Next()) {
    if (cursor_sp->IsError()) {
      last_function_call = &AppendErrorToFunctionCallForest(last_function_call,
                                                            cursor_sp, roots);
      prev_symbol_info = {};
    } else if (cursor_sp->IsInstruction()) {
      TraceDumper::SymbolInfo symbol_info = CalculateSymbolInfo(
          exe_ctx, cursor_sp->GetLoadAddress(), prev_symbol_info);

      last_function_call = &AppendInstructionToFunctionCallForest(
          exe_ctx, last_function_call, prev_symbol_info, symbol_info, cursor_sp,
          roots);
      prev_symbol_info = symbol_info;
    } else if (cursor_sp->GetEventType() == eTraceEventCPUChanged) {
      // TODO: In case of a CPU change, we create a new root because we haven't
      // investigated yet if a call tree can safely continue or if interrupts
      // could have polluted the original call tree.
      last_function_call = nullptr;
      prev_symbol_info = {};
    }
  }

  return roots;
}

void TraceDumper::DumpFunctionCalls() {
  ThreadSP thread_sp = m_cursor_sp->GetExecutionContextRef().GetThreadSP();
  ExecutionContext exe_ctx;
  thread_sp->GetProcess()->GetTarget().CalculateExecutionContext(exe_ctx);

  m_writer_up->FunctionCallForest(
      CreateFunctionCallForest(m_cursor_sp, exe_ctx));
}
