//===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/ThreadPlanBase.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
//
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanBase: This one always stops, and never has anything particular
// to do.
// FIXME: The "signal handling" policies should probably go here.
//----------------------------------------------------------------------

ThreadPlanBase::ThreadPlanBase(Thread &thread)
    : ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes,
                 eVoteNoOpinion) {
// Set the tracer to a default tracer.
// FIXME: need to add a thread settings variable to pix various tracers...
#define THREAD_PLAN_USE_ASSEMBLY_TRACER 1

#ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER
  ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(m_thread));
#else
  ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread));
#endif
  new_tracer_sp->EnableTracing(m_thread.GetTraceEnabledState());
  SetThreadPlanTracer(new_tracer_sp);
  SetIsMasterPlan(true);
}

ThreadPlanBase::~ThreadPlanBase() {}

void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) {
  s->Printf("Base thread plan.");
}

bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; }

bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) {
  // The base plan should defer to its tracer, since by default it
  // always handles the stop.
  if (TracerExplainsStop())
    return false;
  else
    return true;
}

Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) {
  StopInfoSP stop_info_sp = m_thread.GetStopInfo();
  if (stop_info_sp) {
    bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
    if (should_notify)
      return eVoteYes;
    else
      return eVoteNoOpinion;
  } else
    return eVoteNoOpinion;
}

bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
  m_stop_vote = eVoteYes;
  m_run_vote = eVoteYes;

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));

  StopInfoSP stop_info_sp = GetPrivateStopInfo();
  if (stop_info_sp) {
    StopReason reason = stop_info_sp->GetStopReason();
    switch (reason) {
    case eStopReasonInvalid:
    case eStopReasonNone:
      // This
      m_run_vote = eVoteNoOpinion;
      m_stop_vote = eVoteNo;
      return false;

    case eStopReasonBreakpoint:
    case eStopReasonWatchpoint:
      if (stop_info_sp->ShouldStopSynchronous(event_ptr)) {
        // If we are going to stop for a breakpoint, then unship the other plans
        // at this point.  Don't force the discard, however, so Master plans can
        // stay
        // in place if they want to.
        if (log)
          log->Printf(
              "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
              " (breakpoint hit.)",
              m_thread.GetID());
        m_thread.DiscardThreadPlans(false);
        return true;
      }
      // If we aren't going to stop at this breakpoint, and it is internal,
      // don't report this stop or the subsequent running event.
      // Otherwise we will post the stopped & running, but the stopped event
      // will get marked
      // with "restarted" so the UI will know to wait and expect the consequent
      // "running".
      if (stop_info_sp->ShouldNotify(event_ptr)) {
        m_stop_vote = eVoteYes;
        m_run_vote = eVoteYes;
      } else {
        m_stop_vote = eVoteNo;
        m_run_vote = eVoteNo;
      }
      return false;

      // TODO: the break below was missing, was this intentional??? If so
      // please mention it
      break;

    case eStopReasonException:
      // If we crashed, discard thread plans and stop.  Don't force the discard,
      // however,
      // since on rerun the target may clean up this exception and continue
      // normally from there.
      if (log)
        log->Printf(
            "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
            " (exception: %s)",
            m_thread.GetID(), stop_info_sp->GetDescription());
      m_thread.DiscardThreadPlans(false);
      return true;

    case eStopReasonExec:
      // If we crashed, discard thread plans and stop.  Don't force the discard,
      // however,
      // since on rerun the target may clean up this exception and continue
      // normally from there.
      if (log)
        log->Printf(
            "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
            " (exec.)",
            m_thread.GetID());
      m_thread.DiscardThreadPlans(false);
      return true;

    case eStopReasonThreadExiting:
    case eStopReasonSignal:
      if (stop_info_sp->ShouldStop(event_ptr)) {
        if (log)
          log->Printf(
              "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
              " (signal: %s)",
              m_thread.GetID(), stop_info_sp->GetDescription());
        m_thread.DiscardThreadPlans(false);
        return true;
      } else {
        // We're not going to stop, but while we are here, let's figure out
        // whether to report this.
        if (stop_info_sp->ShouldNotify(event_ptr))
          m_stop_vote = eVoteYes;
        else
          m_stop_vote = eVoteNo;
      }
      return false;

    default:
      return true;
    }

  } else {
    m_run_vote = eVoteNoOpinion;
    m_stop_vote = eVoteNo;
  }

  // If there's no explicit reason to stop, then we will continue.
  return false;
}

bool ThreadPlanBase::StopOthers() { return false; }

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

bool ThreadPlanBase::WillStop() { return true; }

bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state,
                                  bool current_plan) {
  // Reset these to the default values so we don't set them wrong, then not get
  // asked
  // for a while, then return the wrong answer.
  m_run_vote = eVoteNoOpinion;
  m_stop_vote = eVoteNo;
  return true;
}

// The base plan is never done.
bool ThreadPlanBase::MischiefManaged() {
  // The base plan is never done.
  return false;
}
