//===-- ThreadPlanStack.cpp -------------------------------------*- C++ -*-===//
//
// 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/ThreadPlanStack.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Utility/Log.h"

using namespace lldb;
using namespace lldb_private;

static void PrintPlanElement(Stream &s, const ThreadPlanSP &plan,
                             lldb::DescriptionLevel desc_level,
                             int32_t elem_idx) {
  s.IndentMore();
  s.Indent();
  s.Printf("Element %d: ", elem_idx);
  plan->GetDescription(&s, desc_level);
  s.EOL();
  s.IndentLess();
}

ThreadPlanStack::ThreadPlanStack(const Thread &thread, bool make_null) {
  if (make_null) {
    // The ThreadPlanNull doesn't do anything to the Thread, so this is actually
    // still a const operation.
    m_plans.push_back(
        ThreadPlanSP(new ThreadPlanNull(const_cast<Thread &>(thread))));
  }
}

void ThreadPlanStack::DumpThreadPlans(Stream &s,
                                      lldb::DescriptionLevel desc_level,
                                      bool include_internal) const {

  uint32_t stack_size;

  s.IndentMore();
  PrintOneStack(s, "Active plan stack", m_plans, desc_level, include_internal);
  PrintOneStack(s, "Completed plan stack", m_completed_plans, desc_level,
                include_internal);
  PrintOneStack(s, "Discarded plan stack", m_discarded_plans, desc_level,
                include_internal);
  s.IndentLess();
}

void ThreadPlanStack::PrintOneStack(Stream &s, llvm::StringRef stack_name,
                                    const PlanStack &stack,
                                    lldb::DescriptionLevel desc_level,
                                    bool include_internal) const {
  // If the stack is empty, just exit:
  if (stack.empty())
    return;

  // Make sure there are public completed plans:
  bool any_public = false;
  if (!include_internal) {
    for (auto plan : stack) {
      if (!plan->GetPrivate()) {
        any_public = true;
        break;
      }
    }
  }

  if (include_internal || any_public) {
    int print_idx = 0;
    s.Indent();
    s.Printf("%s:\n", stack_name);
    for (auto plan : stack) {
      if (!include_internal && plan->GetPrivate())
        continue;
      PrintPlanElement(s, plan, desc_level, print_idx++);
    }
  }
}

size_t ThreadPlanStack::CheckpointCompletedPlans() {
  m_completed_plan_checkpoint++;
  m_completed_plan_store.insert(
      std::make_pair(m_completed_plan_checkpoint, m_completed_plans));
  return m_completed_plan_checkpoint;
}

void ThreadPlanStack::RestoreCompletedPlanCheckpoint(size_t checkpoint) {
  auto result = m_completed_plan_store.find(checkpoint);
  assert(result != m_completed_plan_store.end() &&
         "Asked for a checkpoint that didn't exist");
  m_completed_plans.swap((*result).second);
  m_completed_plan_store.erase(result);
}

void ThreadPlanStack::DiscardCompletedPlanCheckpoint(size_t checkpoint) {
  m_completed_plan_store.erase(checkpoint);
}

void ThreadPlanStack::ThreadDestroyed(Thread *thread) {
  // Tell the plan stacks that this thread is going away:
  for (ThreadPlanSP plan : m_plans)
    plan->ThreadDestroyed();

  for (ThreadPlanSP plan : m_discarded_plans)
    plan->ThreadDestroyed();

  for (ThreadPlanSP plan : m_completed_plans)
    plan->ThreadDestroyed();

  // Now clear the current plan stacks:
  m_plans.clear();
  m_discarded_plans.clear();
  m_completed_plans.clear();

  // Push a ThreadPlanNull on the plan stack.  That way we can continue
  // assuming that the plan stack is never empty, but if somebody errantly asks
  // questions of a destroyed thread without checking first whether it is
  // destroyed, they won't crash.
  if (thread != nullptr) {
    lldb::ThreadPlanSP null_plan_sp(new ThreadPlanNull(*thread));
    m_plans.push_back(null_plan_sp);
  }
}

void ThreadPlanStack::EnableTracer(bool value, bool single_stepping) {
  for (ThreadPlanSP plan : m_plans) {
    if (plan->GetThreadPlanTracer()) {
      plan->GetThreadPlanTracer()->EnableTracing(value);
      plan->GetThreadPlanTracer()->EnableSingleStep(single_stepping);
    }
  }
}

void ThreadPlanStack::SetTracer(lldb::ThreadPlanTracerSP &tracer_sp) {
  for (ThreadPlanSP plan : m_plans)
    plan->SetThreadPlanTracer(tracer_sp);
}

void ThreadPlanStack::PushPlan(lldb::ThreadPlanSP new_plan_sp) {
  // If the thread plan doesn't already have a tracer, give it its parent's
  // tracer:
  // The first plan has to be a base plan:
  assert(m_plans.size() > 0 ||
         new_plan_sp->IsBasePlan() && "Zeroth plan must be a base plan");

  if (!new_plan_sp->GetThreadPlanTracer()) {
    assert(!m_plans.empty());
    new_plan_sp->SetThreadPlanTracer(m_plans.back()->GetThreadPlanTracer());
  }
  m_plans.push_back(new_plan_sp);
  new_plan_sp->DidPush();
}

lldb::ThreadPlanSP ThreadPlanStack::PopPlan() {
  assert(m_plans.size() > 1 && "Can't pop the base thread plan");

  lldb::ThreadPlanSP &plan_sp = m_plans.back();
  m_completed_plans.push_back(plan_sp);
  plan_sp->WillPop();
  m_plans.pop_back();
  return plan_sp;
}

lldb::ThreadPlanSP ThreadPlanStack::DiscardPlan() {
  assert(m_plans.size() > 1 && "Can't discard the base thread plan");

  lldb::ThreadPlanSP &plan_sp = m_plans.back();
  m_discarded_plans.push_back(plan_sp);
  plan_sp->WillPop();
  m_plans.pop_back();
  return plan_sp;
}

// If the input plan is nullptr, discard all plans.  Otherwise make sure this
// plan is in the stack, and if so discard up to and including it.
void ThreadPlanStack::DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr) {
  int stack_size = m_plans.size();

  if (up_to_plan_ptr == nullptr) {
    for (int i = stack_size - 1; i > 0; i--)
      DiscardPlan();
    return;
  }

  bool found_it = false;
  for (int i = stack_size - 1; i > 0; i--) {
    if (m_plans[i].get() == up_to_plan_ptr) {
      found_it = true;
      break;
    }
  }

  if (found_it) {
    bool last_one = false;
    for (int i = stack_size - 1; i > 0 && !last_one; i--) {
      if (GetCurrentPlan().get() == up_to_plan_ptr)
        last_one = true;
      DiscardPlan();
    }
  }
}

void ThreadPlanStack::DiscardAllPlans() {
  int stack_size = m_plans.size();
  for (int i = stack_size - 1; i > 0; i--) {
    DiscardPlan();
  }
  return;
}

void ThreadPlanStack::DiscardConsultingMasterPlans() {
  while (true) {
    int master_plan_idx;
    bool discard = true;

    // Find the first master plan, see if it wants discarding, and if yes
    // discard up to it.
    for (master_plan_idx = m_plans.size() - 1; master_plan_idx >= 0;
         master_plan_idx--) {
      if (m_plans[master_plan_idx]->IsMasterPlan()) {
        discard = m_plans[master_plan_idx]->OkayToDiscard();
        break;
      }
    }

    // If the master plan doesn't want to get discarded, then we're done.
    if (!discard)
      return;

    // First pop all the dependent plans:
    for (int i = m_plans.size() - 1; i > master_plan_idx; i--) {
      DiscardPlan();
    }

    // Now discard the master plan itself.
    // The bottom-most plan never gets discarded.  "OkayToDiscard" for it
    // means discard it's dependent plans, but not it...
    if (master_plan_idx > 0) {
      DiscardPlan();
    }
  }
}

lldb::ThreadPlanSP ThreadPlanStack::GetCurrentPlan() const {
  assert(m_plans.size() != 0 && "There will always be a base plan.");
  return m_plans.back();
}

lldb::ThreadPlanSP ThreadPlanStack::GetCompletedPlan(bool skip_private) const {
  if (m_completed_plans.empty())
    return {};

  if (!skip_private)
    return m_completed_plans.back();

  for (int i = m_completed_plans.size() - 1; i >= 0; i--) {
    lldb::ThreadPlanSP completed_plan_sp;
    completed_plan_sp = m_completed_plans[i];
    if (!completed_plan_sp->GetPrivate())
      return completed_plan_sp;
  }
  return {};
}

lldb::ThreadPlanSP ThreadPlanStack::GetPlanByIndex(uint32_t plan_idx,
                                                   bool skip_private) const {
  uint32_t idx = 0;
  ThreadPlan *up_to_plan_ptr = nullptr;

  for (lldb::ThreadPlanSP plan_sp : m_plans) {
    if (skip_private && plan_sp->GetPrivate())
      continue;
    if (idx == plan_idx)
      return plan_sp;
    idx++;
  }
  return {};
}

lldb::ValueObjectSP ThreadPlanStack::GetReturnValueObject() const {
  if (m_completed_plans.empty())
    return {};

  for (int i = m_completed_plans.size() - 1; i >= 0; i--) {
    lldb::ValueObjectSP return_valobj_sp;
    return_valobj_sp = m_completed_plans[i]->GetReturnValueObject();
    if (return_valobj_sp)
      return return_valobj_sp;
  }
  return {};
}

lldb::ExpressionVariableSP ThreadPlanStack::GetExpressionVariable() const {
  if (m_completed_plans.empty())
    return {};

  for (int i = m_completed_plans.size() - 1; i >= 0; i--) {
    lldb::ExpressionVariableSP expression_variable_sp;
    expression_variable_sp = m_completed_plans[i]->GetExpressionVariable();
    if (expression_variable_sp)
      return expression_variable_sp;
  }
  return {};
}
bool ThreadPlanStack::AnyPlans() const {
  // There is always a base plan...
  return m_plans.size() > 1;
}

bool ThreadPlanStack::AnyCompletedPlans() const {
  return !m_completed_plans.empty();
}

bool ThreadPlanStack::AnyDiscardedPlans() const {
  return !m_discarded_plans.empty();
}

bool ThreadPlanStack::IsPlanDone(ThreadPlan *in_plan) const {
  for (auto plan : m_completed_plans) {
    if (plan.get() == in_plan)
      return true;
  }
  return false;
}

bool ThreadPlanStack::WasPlanDiscarded(ThreadPlan *in_plan) const {
  for (auto plan : m_discarded_plans) {
    if (plan.get() == in_plan)
      return true;
  }
  return false;
}

ThreadPlan *ThreadPlanStack::GetPreviousPlan(ThreadPlan *current_plan) const {
  if (current_plan == nullptr)
    return nullptr;

  // Look first in the completed plans, if the plan is here and there is
  // a completed plan above it, return that.
  int stack_size = m_completed_plans.size();
  for (int i = stack_size - 1; i > 0; i--) {
    if (current_plan == m_completed_plans[i].get())
      return m_completed_plans[i - 1].get();
  }

  // If this is the first completed plan, the previous one is the
  // bottom of the regular plan stack.
  if (stack_size > 0 && m_completed_plans[0].get() == current_plan) {
    return GetCurrentPlan().get();
  }

  // Otherwise look for it in the regular plans.
  stack_size = m_plans.size();
  for (int i = stack_size - 1; i > 0; i--) {
    if (current_plan == m_plans[i].get())
      return m_plans[i - 1].get();
  }
  return nullptr;
}

ThreadPlan *ThreadPlanStack::GetInnermostExpression() const {
  int stack_size = m_plans.size();

  for (int i = stack_size - 1; i > 0; i--) {
    if (m_plans[i]->GetKind() == ThreadPlan::eKindCallFunction)
      return m_plans[i].get();
  }
  return nullptr;
}

void ThreadPlanStack::WillResume() {
  m_completed_plans.clear();
  m_discarded_plans.clear();
}

const ThreadPlanStack::PlanStack &
ThreadPlanStack::GetStackOfKind(ThreadPlanStack::StackKind kind) const {
  switch (kind) {
  case ePlans:
    return m_plans;
  case eCompletedPlans:
    return m_completed_plans;
  case eDiscardedPlans:
    return m_discarded_plans;
  }
  llvm_unreachable("Invalid StackKind value");
}

void ThreadPlanStackMap::Update(ThreadList &current_threads,
                                bool delete_missing,
                                bool check_for_new) {

  // Now find all the new threads and add them to the map:
  if (check_for_new) {
    for (auto thread : current_threads.Threads()) {
      lldb::tid_t cur_tid = thread->GetID();
      if (!Find(cur_tid)) {
        AddThread(*thread.get());
        thread->QueueFundamentalPlan(true);
      }
    }
  }

  // If we aren't reaping missing threads at this point,
  // we are done.
  if (!delete_missing)
    return;
  // Otherwise scan for absent TID's.
  std::vector<lldb::tid_t> missing_threads;
  // If we are going to delete plans from the plan stack,
  // then scan for absent TID's:
  for (auto thread_plans : m_plans_list) {
    lldb::tid_t cur_tid = thread_plans.first;
    ThreadSP thread_sp = current_threads.FindThreadByID(cur_tid);
    if (!thread_sp)
      missing_threads.push_back(cur_tid);
  }
  for (lldb::tid_t tid : missing_threads) {
    RemoveTID(tid);
  }
}

void ThreadPlanStackMap::DumpPlans(Stream &strm,
                                   lldb::DescriptionLevel desc_level,
                                   bool internal, bool condense_if_trivial,
                                   bool skip_unreported) {
  for (auto elem : m_plans_list) {
    lldb::tid_t tid = elem.first;
    uint32_t index_id = 0;
    ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid);

    if (skip_unreported) {
      if (!thread_sp)
        continue;
    }
    if (thread_sp)
      index_id = thread_sp->GetIndexID();

    if (condense_if_trivial) {
      if (!elem.second.AnyPlans() && !elem.second.AnyCompletedPlans() &&
          !elem.second.AnyDiscardedPlans()) {
        strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 "\n", index_id, tid);
        strm.IndentMore();
        strm.Indent();
        strm.Printf("No active thread plans\n");
        strm.IndentLess();
        return;
      }
    }

    strm.Indent();
    strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 ":\n", index_id, tid);

    elem.second.DumpThreadPlans(strm, desc_level, internal);
  }
}

bool ThreadPlanStackMap::DumpPlansForTID(Stream &strm, lldb::tid_t tid,
                                         lldb::DescriptionLevel desc_level,
                                         bool internal,
                                         bool condense_if_trivial,
                                         bool skip_unreported) {
  uint32_t index_id = 0;
  ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid);

  if (skip_unreported) {
    if (!thread_sp) {
      strm.Format("Unknown TID: {0}", tid);
      return false;
    }
  }

  if (thread_sp)
    index_id = thread_sp->GetIndexID();
  ThreadPlanStack *stack = Find(tid);
  if (!stack) {
    strm.Format("Unknown TID: {0}\n", tid);
    return false;
  }

  if (condense_if_trivial) {
    if (!stack->AnyPlans() && !stack->AnyCompletedPlans() &&
        !stack->AnyDiscardedPlans()) {
      strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 "\n", index_id, tid);
      strm.IndentMore();
      strm.Indent();
      strm.Printf("No active thread plans\n");
      strm.IndentLess();
      return true;
    }
  }

  strm.Indent();
  strm.Printf("thread #%u: tid = 0x%4.4" PRIx64 ":\n", index_id, tid);

  stack->DumpThreadPlans(strm, desc_level, internal);
  return true;
}

bool ThreadPlanStackMap::PrunePlansForTID(lldb::tid_t tid) {
  // We only remove the plans for unreported TID's.
  ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(tid);
  if (thread_sp)
    return false;

  return RemoveTID(tid);
}
