//===-- ThreadPlanRunToAddress.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/ThreadPlanRunToAddress.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/Target.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/RegisterContext.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// ThreadPlanRunToAddress: Continue plan
//----------------------------------------------------------------------

ThreadPlanRunToAddress::ThreadPlanRunToAddress
(
    Thread &thread,
    Address &address,
    bool stop_others
) :
    ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_stop_others (stop_others),
    m_addresses (),
    m_break_ids ()
{
    m_addresses.push_back (address.GetOpcodeLoadAddress (m_thread.CalculateTarget().get()));
    SetInitialBreakpoints();
}

ThreadPlanRunToAddress::ThreadPlanRunToAddress
(
    Thread &thread,
    lldb::addr_t address,
    bool stop_others
) :
    ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_stop_others (stop_others),
    m_addresses (),
    m_break_ids ()
{
    m_addresses.push_back(m_thread.CalculateTarget()->GetOpcodeLoadAddress(address));
    SetInitialBreakpoints();
}

ThreadPlanRunToAddress::ThreadPlanRunToAddress
(
    Thread &thread,
    const std::vector<lldb::addr_t> &addresses,
    bool stop_others
) :
    ThreadPlan (ThreadPlan::eKindRunToAddress, "Run to address plan", thread, eVoteNoOpinion, eVoteNoOpinion),
    m_stop_others (stop_others),
    m_addresses (addresses),
    m_break_ids ()
{
    // Convert all addressses into opcode addresses to make sure we set 
    // breakpoints at the correct address.
    Target &target = thread.GetProcess()->GetTarget();
    std::vector<lldb::addr_t>::iterator pos, end = m_addresses.end();
    for (pos = m_addresses.begin(); pos != end; ++pos)
        *pos = target.GetOpcodeLoadAddress (*pos);

    SetInitialBreakpoints();
}

void
ThreadPlanRunToAddress::SetInitialBreakpoints ()
{
    size_t num_addresses = m_addresses.size();
    m_break_ids.resize(num_addresses);
    
    for (size_t i = 0; i < num_addresses; i++)
    {
        Breakpoint *breakpoint;
        breakpoint = m_thread.CalculateTarget()->CreateBreakpoint (m_addresses[i], true).get();
        if (breakpoint != NULL)
        {
            m_break_ids[i] = breakpoint->GetID();
            breakpoint->SetThreadID(m_thread.GetID());
            breakpoint->SetBreakpointKind("run-to-address");
        }
    }
}

ThreadPlanRunToAddress::~ThreadPlanRunToAddress ()
{
    size_t num_break_ids = m_break_ids.size();
    for (size_t i = 0; i <  num_break_ids; i++)
    {
        m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
    }
}

void
ThreadPlanRunToAddress::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    size_t num_addresses = m_addresses.size();
    
    if (level == lldb::eDescriptionLevelBrief)
    {
        if (num_addresses == 0)
        {
            s->Printf ("run to address with no addresses given.");
            return;
        }
        else if (num_addresses == 1)
            s->Printf ("run to address: ");
        else
            s->Printf ("run to addresses: ");
            
        for (size_t i = 0; i < num_addresses; i++)
        {
            s->Address (m_addresses[i], sizeof (addr_t));
            s->Printf(" ");
        }
    }
    else
    {
        if (num_addresses == 0)
        {
            s->Printf ("run to address with no addresses given.");
            return;
        }
        else if (num_addresses == 1)
            s->Printf ("Run to address: ");
        else
        {
            s->Printf ("Run to addresses: ");
        }
            
        for (size_t i = 0; i < num_addresses; i++)
        {
            if (num_addresses > 1)
            {
                s->Printf("\n");
                s->Indent();
            }
            
            s->Address(m_addresses[i], sizeof (addr_t));
            s->Printf (" using breakpoint: %d - ", m_break_ids[i]);
            Breakpoint *breakpoint = m_thread.CalculateTarget()->GetBreakpointByID (m_break_ids[i]).get();
            if (breakpoint)
                breakpoint->Dump (s);
            else
                s->Printf ("but the breakpoint has been deleted.");
        }
    }
}

bool
ThreadPlanRunToAddress::ValidatePlan (Stream *error)
{
    // If we couldn't set the breakpoint for some reason, then this won't
    // work.
    bool all_bps_good = true;
    size_t num_break_ids = m_break_ids.size();
        
    for (size_t i = 0; i < num_break_ids; i++)
    {
        if (m_break_ids[i] == LLDB_INVALID_BREAK_ID)
        {
            all_bps_good = false;
            if (error)
            {
                error->Printf ("Could not set breakpoint for address: ");
                error->Address (m_addresses[i], sizeof (addr_t));
                error->Printf ("\n");
            }
        }
    }
    return all_bps_good;
}

bool
ThreadPlanRunToAddress::PlanExplainsStop (Event *event_ptr)
{
    return AtOurAddress();
}

bool
ThreadPlanRunToAddress::ShouldStop (Event *event_ptr)
{
    return false;
}

bool
ThreadPlanRunToAddress::StopOthers ()
{
    return m_stop_others;
}

void
ThreadPlanRunToAddress::SetStopOthers (bool new_value)
{
    m_stop_others = new_value;
}

StateType
ThreadPlanRunToAddress::GetPlanRunState ()
{
    return eStateRunning;
}

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

bool
ThreadPlanRunToAddress::MischiefManaged ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    if (AtOurAddress())
    {
        // Remove the breakpoint
        size_t num_break_ids = m_break_ids.size();
        
        for (size_t i = 0; i < num_break_ids; i++)
        {
            if (m_break_ids[i] != LLDB_INVALID_BREAK_ID)
            {
                m_thread.CalculateTarget()->RemoveBreakpointByID (m_break_ids[i]);
                m_break_ids[i] = LLDB_INVALID_BREAK_ID;
            }
        }
        if (log)
            log->Printf("Completed run to address plan.");
        ThreadPlan::MischiefManaged ();
        return true;
    }
    else
        return false;
}

bool
ThreadPlanRunToAddress::AtOurAddress ()
{
    lldb::addr_t current_address = m_thread.GetRegisterContext()->GetPC();
    bool found_it = false;
    size_t num_addresses = m_addresses.size();
    for (size_t i = 0; i < num_addresses; i++)
    {
        if (m_addresses[i] == current_address)
        {
            found_it = true;
            break;
        }
    }
    return found_it;
}
