//===-- 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<llvm::StringRef> ToOptionalString(llvm::StringRef s) {
  if (s.empty())
    return std::nullopt;
  return s;
}

static llvm::StringRef GetModuleName(const SymbolContext &sc) {
  if (!sc.module_sp)
    return {};
  return sc.module_sp->GetFileSpec().GetFilename();
}

/// \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 llvm::StringRef GetModuleName(const TraceDumper::TraceItem &item) {
  if (!item.symbol_info)
    return {};
  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.GetFile() == b.GetFile();
}

/// 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 << "  ";
        llvm::StringRef module_name = GetModuleName(item);
        if (module_name.empty())
          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) {
      if (item.timestamp)
        m_s << formatv("[{0:3} ns]", *item.timestamp);
      else
        m_s << "[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;

    llvm::StringRef module_name = GetModuleName(sc);
    if (module_name.empty())
      m_s << "(none)";
    else if (!sc.function && !sc.symbol)
      m_s << module_name << "`(none)";
    else
      m_s << module_name << "`" << sc.GetFunctionName();
  }

  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(nullptr)));

      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.GetFile().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, /*cpu=*/nullptr, /*features=*/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));
}
