//===-- ThreadPlanStepUntil.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/ThreadPlanStepUntil.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

using namespace lldb;
using namespace lldb_private;

// ThreadPlanStepUntil: Run until we reach a given line number or step out of
// the current frame

ThreadPlanStepUntil::ThreadPlanStepUntil(Thread &thread,
                                         llvm::ArrayRef<addr_t> address_list,
                                         bool stop_others, uint32_t frame_idx)
    : ThreadPlan(ThreadPlan::eKindStepUntil, "Step until", thread,
                 eVoteNoOpinion, eVoteNoOpinion),
      m_step_from_insn(LLDB_INVALID_ADDRESS),
      m_return_bp_id(LLDB_INVALID_BREAK_ID),
      m_return_addr(LLDB_INVALID_ADDRESS), m_stepped_out(false),
      m_should_stop(false), m_ran_analyze(false), m_explains_stop(false),
      m_until_points(), m_stop_others(stop_others) {
  StackFrameSP frame_sp(thread.GetStackFrameAtIndex(frame_idx));
  if (!frame_sp)
    return;

  m_step_from_insn = frame_sp->GetStackID().GetPC();
  Target &target = GetTarget();

  // Find the return address and set a breakpoint there:
  // FIXME - can we do this more securely if we know first_insn?

  StackFrameSP return_frame_sp(thread.GetStackFrameAtIndex(frame_idx + 1));
  if (return_frame_sp) {
    // TODO: add inline functionality
    m_return_addr = return_frame_sp->GetStackID().GetPC();
    Breakpoint *return_bp =
        target.CreateBreakpoint(m_return_addr, true, false).get();

    if (return_bp != nullptr) {
      if (return_bp->IsHardware() && !return_bp->HasResolvedLocations())
        m_could_not_resolve_hw_bp = true;
      return_bp->SetThreadID(m_tid);
      m_return_bp_id = return_bp->GetID();
      return_bp->SetBreakpointKind("until-return-backstop");
    }
  }

  m_stack_id = frame_sp->GetStackID();

  for (addr_t address : address_list) {
    Breakpoint *until_bp = target.CreateBreakpoint(address, true, false).get();
    if (until_bp != nullptr) {
      until_bp->SetThreadID(m_tid);
      m_until_points[address] = until_bp->GetID();
      until_bp->SetBreakpointKind("until-target");
    } else {
      m_until_points[address] = LLDB_INVALID_BREAK_ID;
    }
  }
}

ThreadPlanStepUntil::~ThreadPlanStepUntil() { Clear(); }

void ThreadPlanStepUntil::Clear() {
  Target &target = GetTarget();
  if (m_return_bp_id != LLDB_INVALID_BREAK_ID) {
    target.RemoveBreakpointByID(m_return_bp_id);
    m_return_bp_id = LLDB_INVALID_BREAK_ID;
  }

  for (const auto &[address, break_id] : m_until_points)
    target.RemoveBreakpointByID(break_id);
  m_until_points.clear();
  m_could_not_resolve_hw_bp = false;
}

void ThreadPlanStepUntil::GetDescription(Stream *s,
                                         lldb::DescriptionLevel level) {
  if (level == lldb::eDescriptionLevelBrief) {
    s->PutCString("step until");
    if (m_stepped_out)
      s->PutCString(" - stepped out");
    return;
  }

  if (m_until_points.size() == 1) {
    s->Printf("Stepping from address 0x%" PRIx64 " until we reach 0x%" PRIx64
              " using breakpoint %d",
              (uint64_t)m_step_from_insn,
              (uint64_t)(*m_until_points.begin()).first,
              (*m_until_points.begin()).second);
  } else {
    s->Printf("Stepping from address 0x%" PRIx64 " until we reach one of:",
              (uint64_t)m_step_from_insn);
    for (const auto &[address, break_id] : m_until_points)
      s->Printf("\n\t0x%" PRIx64 " (bp: %d)", (uint64_t)address, break_id);
  }
  s->Printf(" stepped out address is 0x%" PRIx64 ".", (uint64_t)m_return_addr);
}

bool ThreadPlanStepUntil::ValidatePlan(Stream *error) {
  if (m_could_not_resolve_hw_bp) {
    if (error)
      error->PutCString(
          "Could not create hardware breakpoint for thread plan.");
    return false;
  }
  if (m_return_bp_id == LLDB_INVALID_BREAK_ID) {
    if (error)
      error->PutCString("Could not create return breakpoint.");
    return false;
  }
  for (const auto &[address, break_id] : m_until_points)
    if (!LLDB_BREAK_ID_IS_VALID(break_id))
      return false;
  return true;
}

void ThreadPlanStepUntil::AnalyzeStop() {
  if (m_ran_analyze)
    return;

  StopInfoSP stop_info_sp = GetPrivateStopInfo();
  m_should_stop = true;
  m_explains_stop = false;

  if (stop_info_sp) {
    StopReason reason = stop_info_sp->GetStopReason();

    if (reason == eStopReasonBreakpoint) {
      // If this is OUR breakpoint, we're fine, otherwise we don't know why
      // this happened...
      BreakpointSiteSP this_site =
          m_process.GetBreakpointSiteList().FindByID(stop_info_sp->GetValue());
      if (!this_site) {
        m_explains_stop = false;
        return;
      }

      if (this_site->IsBreakpointAtThisSite(m_return_bp_id)) {
        // If we are at our "step out" breakpoint, and the stack depth has
        // shrunk, then this is indeed our stop. If the stack depth has grown,
        // then we've hit our step out breakpoint recursively. If we are the
        // only breakpoint at that location, then we do explain the stop, and
        // we'll just continue. If there was another breakpoint here, then we
        // don't explain the stop, but we won't mark ourselves Completed,
        // because maybe that breakpoint will continue, and then we'll finish
        // the "until".
        bool done;
        StackID cur_frame_zero_id;

        done = (m_stack_id.IsYoungerThan(cur_frame_zero_id));

        if (done) {
          m_stepped_out = true;
          SetPlanComplete();
        } else
          m_should_stop = false;

        if (this_site->GetNumberOfConstituents() == 1)
          m_explains_stop = true;
        else
          m_explains_stop = false;
        return;
      } else {
        // Check if we've hit one of our "until" breakpoints.
        until_collection::iterator pos, end = m_until_points.end();
        for (pos = m_until_points.begin(); pos != end; pos++) {
          if (this_site->IsBreakpointAtThisSite((*pos).second)) {
            // If we're at the right stack depth, then we're done.
            Thread &thread = GetThread();
            bool done;
            StackID frame_zero_id =
                thread.GetStackFrameAtIndex(0)->GetStackID();

            if (frame_zero_id == m_stack_id)
              done = true;
            else if (frame_zero_id.IsYoungerThan(m_stack_id))
              done = false;
            else {
              StackFrameSP older_frame_sp = thread.GetStackFrameAtIndex(1);

              // But if we can't even unwind one frame we should just get out
              // of here & stop...
              if (older_frame_sp) {
                const SymbolContext &older_context =
                    older_frame_sp->GetSymbolContext(eSymbolContextEverything);
                SymbolContext stack_context;
                m_stack_id.GetSymbolContextScope()->CalculateSymbolContext(
                    &stack_context);

                done = (older_context == stack_context);
              } else
                done = false;
            }

            if (done)
              SetPlanComplete();
            else
              m_should_stop = false;

            // Otherwise we've hit this breakpoint recursively.  If we're the
            // only breakpoint here, then we do explain the stop, and we'll
            // continue. If not then we should let higher plans handle this
            // stop.
            if (this_site->GetNumberOfConstituents() == 1)
              m_explains_stop = true;
            else {
              m_should_stop = true;
              m_explains_stop = false;
            }
            return;
          }
        }
      }
      // If we get here we haven't hit any of our breakpoints, so let the
      // higher plans take care of the stop.
      m_explains_stop = false;
      return;
    } else if (IsUsuallyUnexplainedStopReason(reason)) {
      m_explains_stop = false;
    } else {
      m_explains_stop = true;
    }
  }
}

bool ThreadPlanStepUntil::DoPlanExplainsStop(Event *event_ptr) {
  // We don't explain signals or breakpoints (breakpoints that handle stepping
  // in or out will be handled by a child plan.
  AnalyzeStop();
  return m_explains_stop;
}

bool ThreadPlanStepUntil::ShouldStop(Event *event_ptr) {
  // If we've told our self in ExplainsStop that we plan to continue, then do
  // so here.  Otherwise, as long as this thread has stopped for a reason, we
  // will stop.

  StopInfoSP stop_info_sp = GetPrivateStopInfo();
  if (!stop_info_sp || stop_info_sp->GetStopReason() == eStopReasonNone)
    return false;

  AnalyzeStop();
  return m_should_stop;
}

bool ThreadPlanStepUntil::StopOthers() { return m_stop_others; }

StateType ThreadPlanStepUntil::GetPlanRunState() { return eStateRunning; }

void ThreadPlanStepUntil::SetUntilPointsEnabled(bool enabled) {
  Target &target = GetTarget();
  for (const auto &[address, break_id] : m_until_points)
    if (BreakpointSP until_bp_sp = target.GetBreakpointByID(break_id))
      until_bp_sp->SetEnabled(enabled);
}

bool ThreadPlanStepUntil::DoWillResume(StateType resume_state,
                                       bool current_plan) {
  if (current_plan) {
    Target &target = GetTarget();
    Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get();
    if (return_bp != nullptr)
      return_bp->SetEnabled(true);
    SetUntilPointsEnabled(true);
  }

  m_should_stop = true;
  m_ran_analyze = false;
  m_explains_stop = false;
  return true;
}

bool ThreadPlanStepUntil::WillStop() {
  Target &target = GetTarget();
  Breakpoint *return_bp = target.GetBreakpointByID(m_return_bp_id).get();
  if (return_bp != nullptr)
    return_bp->SetEnabled(false);
  SetUntilPointsEnabled(false);
  return true;
}

bool ThreadPlanStepUntil::MischiefManaged() {
  if (!IsPlanComplete())
    return false;

  LLDB_LOGF(GetLog(LLDBLog::Step), "Completed step until plan.");
  Clear();
  ThreadPlan::MischiefManaged();
  return true;
}
