//===-- 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::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;
}

