//===-- ThreadPlanStepInstruction.cpp ---------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/ThreadPlanStepInstruction.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_takes_iteration_count = true;
    SetUpState();
}

ThreadPlanStepInstruction::~ThreadPlanStepInstruction() = default;

void
ThreadPlanStepInstruction::SetUpState()
{
    m_instruction_addr = m_thread.GetRegisterContext()->GetPC(0);
    StackFrameSP start_frame_sp(m_thread.GetStackFrameAtIndex(0));
    m_stack_id = start_frame_sp->GetStackID();
    
    m_start_has_symbol = start_frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol != nullptr;
    
    StackFrameSP parent_frame_sp = m_thread.GetStackFrameAtIndex(1);
    if (parent_frame_sp)
        m_parent_frame_id = parent_frame_sp->GetStackID();
}

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_start_has_symbol)
            s->Printf(" which has no symbol");
        
        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::DoPlanExplainsStop (Event *event_ptr)
{
    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
    if (stop_info_sp)
    {
        StopReason reason = stop_info_sp->GetStopReason();
        return (reason == eStopReasonTrace || reason == eStopReasonNone);
    }
    return false;
}

bool
ThreadPlanStepInstruction::IsPlanStale ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
    StackID cur_frame_id = m_thread.GetStackFrameAtIndex(0)->GetStackID();
    if (cur_frame_id == m_stack_id)
    {
        return (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr);
    }
    else if (cur_frame_id < m_stack_id)
    {
        // If the current frame is younger than the start frame and we are stepping over, then we need to continue,
        // but if we are doing just one step, we're done.
        return !m_step_over;
    }
    else
    {
        if (log)
        {
            log->Printf ("ThreadPlanStepInstruction::IsPlanStale - Current frame is older than start frame, plan is stale.");
        }
        return true;
    }
}

bool
ThreadPlanStepInstruction::ShouldStop (Event *event_ptr)
{
    if (m_step_over)
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        
        StackFrameSP cur_frame_sp = m_thread.GetStackFrameAtIndex(0);
        if (!cur_frame_sp)
        {
            if (log)
                log->Printf ("ThreadPlanStepInstruction couldn't get the 0th frame, stopping.");
            SetPlanComplete();
            return true;
        }

        StackID cur_frame_zero_id = cur_frame_sp->GetStackID();
        
        if (cur_frame_zero_id == m_stack_id || m_stack_id < cur_frame_zero_id)
        {
            if (m_thread.GetRegisterContext()->GetPC(0) != m_instruction_addr)
            {
                if (--m_iteration_count <= 0)
                {
                    SetPlanComplete();
                    return true;
                }
                else
                {
                    // We are still stepping, reset the start pc, and in case we've stepped out,
                    // reset the current stack id.
                    SetUpState();
                    return false;
                }
            }
            else
                return false;
        }
        else
        {
            // We've stepped in, step back out again:
            StackFrame *return_frame = m_thread.GetStackFrameAtIndex(1).get();
            if (return_frame)
            {
                if (return_frame->GetStackID() != m_parent_frame_id || m_start_has_symbol)
                {
                    // next-instruction shouldn't step out of inlined functions.  But we may have stepped into a
                    // real function that starts with an inlined function, and we do want to step out of that...

                    if (cur_frame_sp->IsInlined())
                    {
                        StackFrameSP parent_frame_sp = m_thread.GetFrameWithStackID(m_stack_id);

                        if(parent_frame_sp && parent_frame_sp->GetConcreteFrameIndex() == cur_frame_sp->GetConcreteFrameIndex())
                        {
                            SetPlanComplete();
                            if (log)
                            {
                                log->Printf("Frame we stepped into is inlined into the frame we were stepping from, stopping.");
                            }
                            return true;
                        }
                    }

                    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.CalculateTarget()->GetArchitecture().GetAddressByteSize());
                        s.PutCString (" stepping out to: ");
                        addr_t return_addr = return_frame->GetRegisterContext()->GetPC();
                        s.Address (return_addr, m_thread.CalculateTarget()->GetArchitecture().GetAddressByteSize());
                        log->Printf("%s.", s.GetData());
                    }
                    
                    // StepInstruction should probably have the tri-state RunMode, but for now it is safer to
                    // run others.
                    const bool stop_others = false;
                    m_thread.QueueThreadPlanForStepOutNoShouldStop(false,
                                                                   nullptr,
                                                                   true,
                                                                   stop_others,
                                                                   eVoteNo,
                                                                   eVoteNoOpinion,
                                                                   0);
                    return false;
                }
                else
                {
                    if (log)
                    {
                        log->PutCString("The stack id we are stepping in changed, but our parent frame did not when stepping from code with no symbols.  "
                        "We are probably just confused about where we are, stopping.");
                    }
                    SetPlanComplete();
                    return true;
                }
            }
            else
            {
                if (log)
                    log->Printf("Could not find previous frame, stopping.");
                SetPlanComplete();
                return true;
            }
        }
    }
    else
    {
        lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC(0);
        if (pc_addr != m_instruction_addr)
        {
            if (--m_iteration_count <= 0)
            {
                SetPlanComplete();
                return true;
            }
            else
            {
                // We are still stepping, reset the start pc, and in case we've stepped in or out,
                // reset the current stack id.
                SetUpState();
                return false;
            }
        }
        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())
    {
        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
        if (log)
            log->Printf("Completed single instruction step plan.");
        ThreadPlan::MischiefManaged ();
        return true;
    }
    else
    {
        return false;
    }
}
