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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private-log.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanStepInstruction: Step over the current instruction
//----------------------------------------------------------------------

ThreadPlanStepInstruction::ThreadPlanStepInstruction
(
    Thread &thread,
    bool step_over,
    bool stop_other_threads,
    Vote stop_vote,
    Vote run_vote
) :
    ThreadPlan (ThreadPlan::eKindStepInstruction, "Step over single instruction", thread, stop_vote, run_vote),
    m_instruction_addr (0),
    m_stop_other_threads (stop_other_threads),
    m_step_over (step_over),
    m_stack_depth (0)
{
    m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
    m_stack_depth = m_thread.GetStackFrameCount();
}

ThreadPlanStepInstruction::~ThreadPlanStepInstruction ()
{
}

void
ThreadPlanStepInstruction::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    if (level == lldb::eDescriptionLevelBrief)
    {
        if (m_step_over)
            s->Printf ("instruction step over");
        else
            s->Printf ("instruction step into");
    }
    else
    {
        s->Printf ("Stepping one instruction past ");
        s->Address(m_instruction_addr, sizeof (addr_t));
        if (m_step_over)
            s->Printf(" stepping over calls");
        else
            s->Printf(" stepping into calls");
    }
}

bool
ThreadPlanStepInstruction::ValidatePlan (Stream *error)
{
    // Since we read the instruction we're stepping over from the thread,
    // this plan will always work.
    return true;
}

bool
ThreadPlanStepInstruction::PlanExplainsStop ()
{
    StopInfoSP stop_info_sp = GetPrivateStopReason();
    if (stop_info_sp)
    {
        StopReason reason = stop_info_sp->GetStopReason();
        if (reason == eStopReasonTrace || reason == eStopReasonNone)
            return true;
        else
            return false;
    }
    return false;
}

bool
ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
{
    if (m_step_over)
    {
        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (m_thread.GetStackFrameCount() <= m_stack_depth)
        {
            if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
            {
                SetPlanComplete();
                return true;
            }
            else
                return false;
        }
        else
        {
            // We've stepped in, step back out again:
            StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
            if (return_frame)
            {
                if (log)
                {
                    StreamString s;
                    s.PutCString ("Stepped in to: ");
                    addr_t stop_addr = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
                    s.Address (stop_addr, m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
                    s.PutCString (" stepping out to: ");
                    addr_t return_addr = return_frame->GetRegisterContext()->GetPC();
                    s.Address (return_addr, m_thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
                    log->Printf("%s.", s.GetData());
                }
                m_thread.QueueThreadPlanForStepOut(false, NULL, true, m_stop_other_threads, eVoteNo, eVoteNoOpinion, 0);
                return false;
            }
            else
            {
                if (log)
                    log->Printf("Could not find previous frame, stopping.");
                SetPlanComplete();
                return true;
            }

        }

    }
    else
    {
        if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
        {
            SetPlanComplete();
            return true;
        }
        else
            return false;
    }
}

bool
ThreadPlanStepInstruction::StopOthers ()
{
    return m_stop_other_threads;
}

StateType
ThreadPlanStepInstruction::GetPlanRunState ()
{
    return eStateStepping;
}

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

bool
ThreadPlanStepInstruction::MischiefManaged ()
{
    if (IsPlanComplete())
    {
        LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (log)
            log->Printf("Completed single instruction step plan.");
        ThreadPlan::MischiefManaged ();
        return true;
    }
    else
    {
        return false;
    }
}

