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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlan constructor
//----------------------------------------------------------------------
ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) :
    m_thread (thread),
    m_stop_vote (stop_vote),
    m_run_vote (run_vote),
    m_kind (kind),
    m_name (name),
    m_plan_complete_mutex (Mutex::eMutexTypeRecursive),
    m_plan_complete (false),
    m_plan_private (false),
    m_okay_to_discard (true),
    m_is_master_plan (false),
    m_plan_succeeded(true)
{
    SetID (GetNextID());
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
ThreadPlan::~ThreadPlan()
{
}

bool
ThreadPlan::IsPlanComplete ()
{
    Mutex::Locker locker(m_plan_complete_mutex);
    return m_plan_complete;
}

void
ThreadPlan::SetPlanComplete (bool success)
{
    Mutex::Locker locker(m_plan_complete_mutex);
    m_plan_complete = true;
    m_plan_succeeded = success;
}

bool
ThreadPlan::MischiefManaged ()
{
    Mutex::Locker locker(m_plan_complete_mutex);
    // Mark the plan is complete, but don't override the success flag.
    m_plan_complete = true;
    return true;
}

Vote
ThreadPlan::ShouldReportStop (Event *event_ptr)
{
    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    if (m_stop_vote == eVoteNoOpinion)
    {
        ThreadPlan *prev_plan = GetPreviousPlan ();
        if (prev_plan)
        {
            Vote prev_vote = prev_plan->ShouldReportStop (event_ptr);
            if (log)
                log->Printf ("ThreadPlan::ShouldReportStop() returning previous thread plan vote: %s", 
                             GetVoteAsCString (prev_vote));
            return prev_vote;
        }
    }
    if (log)
        log->Printf ("ThreadPlan::ShouldReportStop() returning vote: %s", GetVoteAsCString (m_stop_vote));
    return m_stop_vote;
}

Vote
ThreadPlan::ShouldReportRun (Event *event_ptr)
{
    if (m_run_vote == eVoteNoOpinion)
    {
        ThreadPlan *prev_plan = GetPreviousPlan ();
        if (prev_plan)
            return prev_plan->ShouldReportRun (event_ptr);
    }
    return m_run_vote;
}

bool
ThreadPlan::StopOthers ()
{
    ThreadPlan *prev_plan;
    prev_plan = GetPreviousPlan ();
    if (prev_plan == NULL)
        return false;
    else
        return prev_plan->StopOthers();
}

void
ThreadPlan::SetStopOthers (bool new_value)
{
	// SetStopOthers doesn't work up the hierarchy.  You have to set the 
    // explicit ThreadPlan you want to affect.
}

bool
ThreadPlan::WillResume (StateType resume_state, bool current_plan)
{
    if (current_plan)
    {
        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

        if (log)
        {
            RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
            addr_t pc = reg_ctx->GetPC();
            addr_t sp = reg_ctx->GetSP();
            addr_t fp = reg_ctx->GetFP();
            log->Printf("%s Thread #%u: tid = 0x%4.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, "
                        "plan = '%s', state = %s, stop others = %d", 
                        __FUNCTION__,
                        m_thread.GetIndexID(), 
                        m_thread.GetID(),  
                        (uint64_t)pc,
                        (uint64_t)sp,
                        (uint64_t)fp,
                        m_name.c_str(), 
                        StateAsCString(resume_state), 
                        StopOthers());
        }
    }
    return true;
}

lldb::user_id_t
ThreadPlan::GetNextID()
{
    static uint32_t g_nextPlanID = 0;
    return ++g_nextPlanID;
}

void
ThreadPlan::DidPush()
{
}

void
ThreadPlan::WillPop()
{
}

bool
ThreadPlan::OkayToDiscard()
{
    if (!IsMasterPlan())
        return true;
    else
        return m_okay_to_discard;
}

lldb::StateType
ThreadPlan::RunState ()
{
    if (m_tracer_sp && m_tracer_sp->TracingEnabled() && m_tracer_sp->SingleStepEnabled())
        return eStateStepping;
    else
        return GetPlanRunState();
}
