//===-- 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/StoppointCallbackContext.h"
#include "lldb/Breakpoint/BreakpointSite.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/Breakpoint.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::PlanExplainsStop ()
{
    // The base plan should defer to its tracer, since by default it
    // always handles the stop.
    if (TracerExplainsStop())
        return false;
    else
        return true;
}

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

    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    StopInfoSP stop_info_sp = GetPrivateStopReason();
    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->ShouldStop(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.4llx (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.4llx (exception.)", m_thread.GetID());
            m_thread.DiscardThreadPlans(false);
            return true;

        case eStopReasonSignal:
            if (stop_info_sp->ShouldStop(event_ptr))
            {
                if (log)
                    log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4llx (signal.)", m_thread.GetID());
                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::WillResume (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;
}

