//===-- 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 {
  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 << stack_name << ":\n";
    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 = std::move(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 = std::move(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;

  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::ClearThreadCache() {
  for (lldb::ThreadPlanSP thread_plan_sp : m_plans)
    thread_plan_sp->ClearThreadCache();
}

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

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);
}
