//===-- 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.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.)", m_thread.GetID());
            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 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.)", 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;
}

