//===-- 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/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 addresses 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, false).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::DoPlanExplainsStop (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;
}
