//===-- ThreadPlan.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/ThreadPlan.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"

#include <atomic>

using namespace lldb;
using namespace lldb_private;

// ThreadPlan constructor
ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread,
                       Vote report_stop_vote, Vote report_run_vote)
    : m_process(*thread.GetProcess().get()), m_tid(thread.GetID()),
      m_report_stop_vote(report_stop_vote), m_report_run_vote(report_run_vote),
      m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false),
      m_thread(&thread), m_kind(kind), m_name(name), m_plan_complete_mutex(),
      m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false),
      m_plan_private(false), m_okay_to_discard(true),
      m_is_controlling_plan(false), m_plan_succeeded(true) {
  SetID(GetNextID());
}

// Destructor
ThreadPlan::~ThreadPlan() = default;

Target &ThreadPlan::GetTarget() { return m_process.GetTarget(); }

const Target &ThreadPlan::GetTarget() const { return m_process.GetTarget(); }

Thread &ThreadPlan::GetThread() {
  if (m_thread)
    return *m_thread;

  ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(m_tid);
  m_thread = thread_sp.get();
  return *m_thread;
}

bool ThreadPlan::PlanExplainsStop(Event *event_ptr) {
  if (m_cached_plan_explains_stop == eLazyBoolCalculate) {
    bool actual_value = DoPlanExplainsStop(event_ptr);
    CachePlanExplainsStop(actual_value);
    return actual_value;
  } else {
    return m_cached_plan_explains_stop == eLazyBoolYes;
  }
}

bool ThreadPlan::IsPlanComplete() {
  std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
  return m_plan_complete;
}

void ThreadPlan::SetPlanComplete(bool success) {
  std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
  m_plan_complete = true;
  m_plan_succeeded = success;
}

bool ThreadPlan::MischiefManaged() {
  std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
  // Mark the plan is complete, but don't override the success flag.
  m_plan_complete = true;
  return true;
}

Vote ThreadPlan::ShouldReportStop(Event *event_ptr) {
  Log *log = GetLog(LLDBLog::Step);

  if (m_report_stop_vote == eVoteNoOpinion) {
    ThreadPlan *prev_plan = GetPreviousPlan();
    if (prev_plan) {
      Vote prev_vote = prev_plan->ShouldReportStop(event_ptr);
      LLDB_LOG(log, "returning previous thread plan vote: {0}", prev_vote);
      return prev_vote;
    }
  }
  LLDB_LOG(log, "Returning vote: {0}", m_report_stop_vote);
  return m_report_stop_vote;
}

Vote ThreadPlan::ShouldReportRun(Event *event_ptr) {
  if (m_report_run_vote == eVoteNoOpinion) {
    ThreadPlan *prev_plan = GetPreviousPlan();
    if (prev_plan)
      return prev_plan->ShouldReportRun(event_ptr);
  }
  return m_report_run_vote;
}

void ThreadPlan::ClearThreadCache() { m_thread = nullptr; }

bool ThreadPlan::StopOthers() {
  ThreadPlan *prev_plan;
  prev_plan = GetPreviousPlan();
  return (prev_plan == nullptr) ? false : prev_plan->StopOthers();
}

void ThreadPlan::SetStopOthers(bool new_value) {
  // SetStopOthers doesn't work up the hierarchy.  You have to set the explicit
  // ThreadPlan you want to affect.
}

bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) {
  m_cached_plan_explains_stop = eLazyBoolCalculate;

  if (current_plan) {
    Log *log = GetLog(LLDBLog::Step);

    if (log) {
      RegisterContext *reg_ctx = GetThread().GetRegisterContext().get();
      assert(reg_ctx);
      addr_t pc = reg_ctx->GetPC();
      addr_t sp = reg_ctx->GetSP();
      addr_t fp = reg_ctx->GetFP();
      LLDB_LOGF(
          log,
          "%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64
          ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "
          "plan = '%s', state = %s, stop others = %d",
          __FUNCTION__, GetThread().GetIndexID(),
          static_cast<void *>(&GetThread()), m_tid, static_cast<uint64_t>(pc),
          static_cast<uint64_t>(sp), static_cast<uint64_t>(fp), m_name.c_str(),
          StateAsCString(resume_state), StopOthers());
    }
  }
  bool success = DoWillResume(resume_state, current_plan);
  ClearThreadCache(); // We don't cache the thread pointer over resumes.  This
                      // Thread might go away, and another Thread represent
                      // the same underlying object on a later stop.
  return success;
}

lldb::user_id_t ThreadPlan::GetNextID() {
  static std::atomic<uint32_t> g_nextPlanID{0};
  return ++g_nextPlanID;
}

void ThreadPlan::DidPush() {}

void ThreadPlan::DidPop() {}

bool ThreadPlan::OkayToDiscard() {
  return IsControllingPlan() ? m_okay_to_discard : true;
}

lldb::StateType ThreadPlan::RunState() {
  if (m_tracer_sp && m_tracer_sp->TracingEnabled())
    return eStateStepping;
  else
    return GetPlanRunState();
}

bool ThreadPlan::IsUsuallyUnexplainedStopReason(lldb::StopReason reason) {
  switch (reason) {
  case eStopReasonWatchpoint:
  case eStopReasonSignal:
  case eStopReasonException:
  case eStopReasonExec:
  case eStopReasonThreadExiting:
  case eStopReasonInstrumentation:
  case eStopReasonFork:
  case eStopReasonVFork:
  case eStopReasonVForkDone:
  case eStopReasonInterrupt:
    return true;
  default:
    return false;
  }
}

// ThreadPlanNull

ThreadPlanNull::ThreadPlanNull(Thread &thread)
    : ThreadPlan(ThreadPlan::eKindNull, "Null Thread Plan", thread,
                 eVoteNoOpinion, eVoteNoOpinion) {}

ThreadPlanNull::~ThreadPlanNull() = default;

void ThreadPlanNull::GetDescription(Stream *s, lldb::DescriptionLevel level) {
  s->PutCString("Null thread plan - thread has been destroyed.");
}

bool ThreadPlanNull::ValidatePlan(Stream *error) {
#ifdef LLDB_CONFIGURATION_DEBUG
  fprintf(stderr,
          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
          ", ptid = 0x%" PRIx64 ")",
          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#else
  Log *log = GetLog(LLDBLog::Thread);
  LLDB_LOGF(log,
            "error: %s called on thread that has been destroyed "
            "(tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
            LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#endif
  return true;
}

bool ThreadPlanNull::ShouldStop(Event *event_ptr) {
#ifdef LLDB_CONFIGURATION_DEBUG
  fprintf(stderr,
          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
          ", ptid = 0x%" PRIx64 ")",
          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#else
  Log *log = GetLog(LLDBLog::Thread);
  LLDB_LOGF(log,
            "error: %s called on thread that has been destroyed "
            "(tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
            LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#endif
  return true;
}

bool ThreadPlanNull::WillStop() {
#ifdef LLDB_CONFIGURATION_DEBUG
  fprintf(stderr,
          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
          ", ptid = 0x%" PRIx64 ")",
          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#else
  Log *log = GetLog(LLDBLog::Thread);
  LLDB_LOGF(log,
            "error: %s called on thread that has been destroyed "
            "(tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
            LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#endif
  return true;
}

bool ThreadPlanNull::DoPlanExplainsStop(Event *event_ptr) {
#ifdef LLDB_CONFIGURATION_DEBUG
  fprintf(stderr,
          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
          ", ptid = 0x%" PRIx64 ")",
          LLVM_PRETTY_FUNCTION, GetThread().GetID(), GetThread().GetProtocolID());
#else
  Log *log = GetLog(LLDBLog::Thread);
  LLDB_LOGF(log,
            "error: %s called on thread that has been destroyed "
            "(tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
            LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#endif
  return true;
}

// The null plan is never done.
bool ThreadPlanNull::MischiefManaged() {
// The null plan is never done.
#ifdef LLDB_CONFIGURATION_DEBUG
  fprintf(stderr,
          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
          ", ptid = 0x%" PRIx64 ")",
          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#else
  Log *log = GetLog(LLDBLog::Thread);
  LLDB_LOGF(log,
            "error: %s called on thread that has been destroyed "
            "(tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
            LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#endif
  return false;
}

lldb::StateType ThreadPlanNull::GetPlanRunState() {
// Not sure what to return here.  This is a dead thread.
#ifdef LLDB_CONFIGURATION_DEBUG
  fprintf(stderr,
          "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
          ", ptid = 0x%" PRIx64 ")",
          LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#else
  Log *log = GetLog(LLDBLog::Thread);
  LLDB_LOGF(log,
            "error: %s called on thread that has been destroyed "
            "(tid = 0x%" PRIx64 ", ptid = 0x%" PRIx64 ")",
            LLVM_PRETTY_FUNCTION, m_tid, GetThread().GetProtocolID());
#endif
  return eStateRunning;
}

llvm::Expected<std::vector<addr_t>> lldb_private::GetStepUntilAddresses(
    StackFrame &frame, const FileSpec &file, llvm::ArrayRef<uint32_t> lines,
    llvm::ArrayRef<addr_t> requested_addresses) {
  const SymbolContext &frame_sc =
      frame.GetSymbolContext(eSymbolContextCompUnit | eSymbolContextFunction);
  TargetSP target_sp = frame.CalculateTarget();
  if (!target_sp)
    return llvm::createStringError("null target from StepUntil frame");
  if (!frame_sc.comp_unit || !frame_sc.function)
    return llvm::createStringError("frame has no function debug information");

  std::vector<addr_t> until_addrs;
  auto add_if_in_scope = [&](const Address &addr) {
    addr_t load_addr = addr.GetLoadAddress(target_sp.get());
    if (load_addr != LLDB_INVALID_ADDRESS && frame.IsAddressInFrameScope(addr))
      until_addrs.push_back(load_addr);
  };

  bool found_some_line_table_entry = false;
  for (uint32_t line : lines) {
    LineEntry line_entry;
    uint32_t idx = frame_sc.comp_unit->FindLineEntry(
        0, line, &file, /*exact=*/false, &line_entry);
    if (idx == UINT32_MAX)
      continue;
    found_some_line_table_entry = true;
    const uint32_t actual_line = line_entry.line;
    while (idx != UINT32_MAX) {
      add_if_in_scope(line_entry.range.GetBaseAddress());
      idx = frame_sc.comp_unit->FindLineEntry(idx + 1, actual_line, &file,
                                              /*exact=*/true, &line_entry);
    }
  }

  for (addr_t address : requested_addresses) {
    Address addr;
    if (target_sp->ResolveLoadAddress(address, addr))
      add_if_in_scope(addr);
  }

  if (!until_addrs.empty())
    return until_addrs;
  // Historically, LLDB has emphasized the error when "only lines were
  // requested, but none of those lines had a line table entry".
  if (requested_addresses.empty() && !found_some_line_table_entry)
    return llvm::createStringError("No line entries matching until target");
  return llvm::createStringError(
      "Until target outside of the current function");
}
