//===-- SBBreakpoint.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/API/SBBreakpoint.h"
#include "lldb/API/SBBreakpointLocation.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBThread.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"


#include "lldb/lldb-enumerations.h"

using namespace lldb;
using namespace lldb_private;

struct CallbackData
{
    SBBreakpoint::BreakpointHitCallback callback;
    void *callback_baton;
};

class SBBreakpointCallbackBaton : public Baton
{
public:

    SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
        Baton (new CallbackData)
    {
        CallbackData *data = (CallbackData *)m_data;
        data->callback = callback;
        data->callback_baton = baton;
    }
    
    virtual ~SBBreakpointCallbackBaton()
    {
        CallbackData *data = (CallbackData *)m_data;

        if (data)
        {
            delete data;
            m_data = NULL;
        }
    }
};


SBBreakpoint::SBBreakpoint () :
    m_opaque_sp ()
{
}

SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
    m_opaque_sp (rhs.m_opaque_sp)
{
}


SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
    m_opaque_sp (bp_sp)
{
}

SBBreakpoint::~SBBreakpoint()
{
}

const SBBreakpoint &
SBBreakpoint::operator = (const SBBreakpoint& rhs)
{
    if (this != &rhs)
        m_opaque_sp = rhs.m_opaque_sp;
    return *this;
}

bool
SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs)
{
    if (m_opaque_sp && rhs.m_opaque_sp)
        return m_opaque_sp.get() == rhs.m_opaque_sp.get();
    return false;
}

bool
SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs)
{
    if (m_opaque_sp && rhs.m_opaque_sp)
        return m_opaque_sp.get() != rhs.m_opaque_sp.get();
    return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
}

break_id_t
SBBreakpoint::GetID () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    break_id_t break_id = LLDB_INVALID_BREAK_ID;
    if (m_opaque_sp)
        break_id = m_opaque_sp->GetID();

    if (log)
    {
        if (break_id == LLDB_INVALID_BREAK_ID)
            log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
                         static_cast<void*>(m_opaque_sp.get()));
        else
            log->Printf ("SBBreakpoint(%p)::GetID () => %u",
                         static_cast<void*>(m_opaque_sp.get()), break_id);
    }

    return break_id;
}


bool
SBBreakpoint::IsValid() const
{
    if (!m_opaque_sp)
        return false;
    else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
       return true;
    else
        return false;
}

void
SBBreakpoint::ClearAllBreakpointSites ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->ClearAllBreakpointSites ();
    }
}

SBBreakpointLocation
SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
{
    SBBreakpointLocation sb_bp_location;

    if (m_opaque_sp)
    {
        if (vm_addr != LLDB_INVALID_ADDRESS)
        {
            Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
            Address address;
            Target &target = m_opaque_sp->GetTarget();
            if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
            {
                address.SetRawAddress (vm_addr);
            }
            sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
        }
    }
    return sb_bp_location;
}

break_id_t
SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
{
    break_id_t break_id = LLDB_INVALID_BREAK_ID;

    if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        Address address;
        Target &target = m_opaque_sp->GetTarget();
        if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false)
        {
            address.SetRawAddress (vm_addr);
        }
        break_id = m_opaque_sp->FindLocationIDByAddress (address);
    }

    return break_id;
}

SBBreakpointLocation
SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
{
    SBBreakpointLocation sb_bp_location;

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
    }

    return sb_bp_location;
}

SBBreakpointLocation
SBBreakpoint::GetLocationAtIndex (uint32_t index)
{
    SBBreakpointLocation sb_bp_location;

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
    }

    return sb_bp_location;
}

void
SBBreakpoint::SetEnabled (bool enable)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
                     static_cast<void*>(m_opaque_sp.get()), enable);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetEnabled (enable);
    }
}

bool
SBBreakpoint::IsEnabled ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->IsEnabled();
    }
    else
        return false;
}

void
SBBreakpoint::SetOneShot (bool one_shot)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
                     static_cast<void*>(m_opaque_sp.get()), one_shot);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetOneShot (one_shot);
    }
}

bool
SBBreakpoint::IsOneShot () const
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->IsOneShot();
    }
    else
        return false;
}

bool
SBBreakpoint::IsInternal ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->IsInternal();
    }
    else
        return false;
}

void
SBBreakpoint::SetIgnoreCount (uint32_t count)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
                     static_cast<void*>(m_opaque_sp.get()), count);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetIgnoreCount (count);
    }
}

void
SBBreakpoint::SetCondition (const char *condition)
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetCondition (condition);
    }
}

const char *
SBBreakpoint::GetCondition ()
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        return m_opaque_sp->GetConditionText ();
    }
    return NULL;
}

uint32_t
SBBreakpoint::GetHitCount () const
{
    uint32_t count = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        count = m_opaque_sp->GetHitCount();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u",
                     static_cast<void*>(m_opaque_sp.get()), count);

    return count;
}

uint32_t
SBBreakpoint::GetIgnoreCount () const
{
    uint32_t count = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        count = m_opaque_sp->GetIgnoreCount();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u",
                     static_cast<void*>(m_opaque_sp.get()), count);

    return count;
}

void
SBBreakpoint::SetThreadID (tid_t tid)
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->SetThreadID (tid);
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
                     static_cast<void*>(m_opaque_sp.get()), tid);

}

tid_t
SBBreakpoint::GetThreadID ()
{
    tid_t tid = LLDB_INVALID_THREAD_ID;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        tid = m_opaque_sp->GetThreadID();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
                     static_cast<void*>(m_opaque_sp.get()), tid);
    return tid;
}

void
SBBreakpoint::SetThreadIndex (uint32_t index)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)",
                     static_cast<void*>(m_opaque_sp.get()), index);
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
    }
}

uint32_t
SBBreakpoint::GetThreadIndex() const
{
    uint32_t thread_idx = UINT32_MAX;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
        if (thread_spec != NULL)
            thread_idx = thread_spec->GetIndex();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u",
                     static_cast<void*>(m_opaque_sp.get()), thread_idx);

    return thread_idx;
}

void
SBBreakpoint::SetThreadName (const char *thread_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)",
                     static_cast<void*>(m_opaque_sp.get()), thread_name);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
    }
}

const char *
SBBreakpoint::GetThreadName () const
{
    const char *name = NULL;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
        if (thread_spec != NULL)
            name = thread_spec->GetName();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s",
                     static_cast<void*>(m_opaque_sp.get()), name);

    return name;
}

void
SBBreakpoint::SetQueueName (const char *queue_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)",
                     static_cast<void*>(m_opaque_sp.get()), queue_name);
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
    }
}

const char *
SBBreakpoint::GetQueueName () const
{
    const char *name = NULL;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
        if (thread_spec)
            name = thread_spec->GetQueueName();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s",
                     static_cast<void*>(m_opaque_sp.get()), name);

    return name;
}

size_t
SBBreakpoint::GetNumResolvedLocations() const
{
    size_t num_resolved = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        num_resolved = m_opaque_sp->GetNumResolvedLocations();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
                     static_cast<void*>(m_opaque_sp.get()),
                     static_cast<uint64_t>(num_resolved));
    return num_resolved;
}

size_t
SBBreakpoint::GetNumLocations() const
{
    size_t num_locs = 0;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        num_locs = m_opaque_sp->GetNumLocations();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
                     static_cast<void*>(m_opaque_sp.get()),
                     static_cast<uint64_t>(num_locs));
    return num_locs;
}

bool
SBBreakpoint::GetDescription (SBStream &s)
{
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
        m_opaque_sp->GetResolverDescription (s.get());
        m_opaque_sp->GetFilterDescription (s.get());
        const size_t num_locations = m_opaque_sp->GetNumLocations ();
        s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
        return true;
    }
    s.Printf ("No value");
    return false;
}

bool
SBBreakpoint::PrivateBreakpointHitCallback 
(
    void *baton, 
    StoppointCallbackContext *ctx, 
    lldb::user_id_t break_id, 
    lldb::user_id_t break_loc_id
)
{
    ExecutionContext exe_ctx (ctx->exe_ctx_ref);
    BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
    if (baton && bp_sp)
    {
        CallbackData *data = (CallbackData *)baton;
        lldb_private::Breakpoint *bp = bp_sp.get();
        if (bp && data->callback)
        {
            Process *process = exe_ctx.GetProcessPtr();
            if (process)
            {
                SBProcess sb_process (process->shared_from_this());
                SBThread sb_thread;
                SBBreakpointLocation sb_location;
                assert (bp_sp);
                sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
                Thread *thread = exe_ctx.GetThreadPtr();
                if (thread)
                    sb_thread.SetThread(thread->shared_from_this());

                return data->callback (data->callback_baton, 
                                          sb_process, 
                                          sb_thread, 
                                          sb_location);
            }
        }
    }
    return true;    // Return true if we should stop at this breakpoint
}

void
SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
    {
        void *pointer = &callback;
        log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
                     static_cast<void*>(m_opaque_sp.get()),
                     *static_cast<void**>(&pointer), static_cast<void*>(baton));
    }

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
        m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
    }
}

void
SBBreakpoint::SetScriptCallbackFunction (const char *callback_function_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
                     static_cast<void*>(m_opaque_sp.get()),
                     callback_function_name);

    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
        m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options,
                                                                                                                                                   callback_function_name);
    }
}

SBError
SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
                     static_cast<void*>(m_opaque_sp.get()), callback_body_text);

    SBError sb_error;
    if (m_opaque_sp)
    {
        Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
        BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
        Error error =  m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
                                                                                                                                    callback_body_text);
        sb_error.SetError(error);
    }
    else
        sb_error.SetErrorString("invalid breakpoint");

    return sb_error;
}

lldb_private::Breakpoint *
SBBreakpoint::operator->() const
{
    return m_opaque_sp.get();
}

lldb_private::Breakpoint *
SBBreakpoint::get() const
{
    return m_opaque_sp.get();
}

lldb::BreakpointSP &
SBBreakpoint::operator *()
{
    return m_opaque_sp;
}

const lldb::BreakpointSP &
SBBreakpoint::operator *() const
{
    return m_opaque_sp;
}

bool
SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event)
{
    return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL;

}

BreakpointEventType
SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
{
    if (event.IsValid())
        return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
    return eBreakpointEventTypeInvalidType;
}

SBBreakpoint
SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
{
    SBBreakpoint sb_breakpoint;
    if (event.IsValid())
        sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
    return sb_breakpoint;
}

SBBreakpointLocation
SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
{
    SBBreakpointLocation sb_breakpoint_loc;
    if (event.IsValid())
        sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
    return sb_breakpoint_loc;
}

uint32_t
SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event)
{
    uint32_t num_locations = 0;
    if (event.IsValid())
        num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP()));
    return num_locations;
}


