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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

BreakpointList::BreakpointList (bool is_internal) :
    m_mutex (Mutex::eMutexTypeRecursive),
    m_breakpoints(),
    m_next_break_id (0),
    m_is_internal (is_internal)
{
}

BreakpointList::~BreakpointList()
{
}


break_id_t
BreakpointList::Add (BreakpointSP &bp_sp, bool notify)
{
    Mutex::Locker locker(m_mutex);
    // Internal breakpoint IDs are negative, normal ones are positive
    bp_sp->SetID (m_is_internal ? --m_next_break_id : ++m_next_break_id);
    
    m_breakpoints.push_back(bp_sp);
    if (notify)
    {
        if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
            bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
                                               new Breakpoint::BreakpointEventData (eBreakpointEventTypeAdded, bp_sp));
    }
    return bp_sp->GetID();
}

bool
BreakpointList::Remove (break_id_t break_id, bool notify)
{
    Mutex::Locker locker(m_mutex);
    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);    // Predicate
    if (pos != m_breakpoints.end())
    {
        BreakpointSP bp_sp (*pos);
        m_breakpoints.erase(pos);
        if (notify)
        {
            if (bp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
                bp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
                                                   new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, bp_sp));
        }
        return true;
    }
    return false;
}

void
BreakpointList::RemoveInvalidLocations (const ArchSpec &arch)
{
    Mutex::Locker locker(m_mutex);
    for (const auto &bp_sp : m_breakpoints)
        bp_sp->RemoveInvalidLocations(arch);
}


void
BreakpointList::SetEnabledAll (bool enabled)
{
    Mutex::Locker locker(m_mutex);
    for (const auto &bp_sp : m_breakpoints)
        bp_sp->SetEnabled (enabled);
}


void
BreakpointList::RemoveAll (bool notify)
{
    Mutex::Locker locker(m_mutex);
    ClearAllBreakpointSites ();

    if (notify)
    {
        bp_collection::iterator pos, end = m_breakpoints.end();
        for (pos = m_breakpoints.begin(); pos != end; ++pos)
        {
            if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
            {
                (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
                                                    new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
                                                                                         *pos));
            }
        }
    }
    m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
}

class BreakpointIDMatches
{
public:
    BreakpointIDMatches (break_id_t break_id) :
        m_break_id(break_id)
    {
    }

    bool operator() (const BreakpointSP &bp) const
    {
        return m_break_id == bp->GetID();
    }

private:
   const break_id_t m_break_id;
};

BreakpointList::bp_collection::iterator
BreakpointList::GetBreakpointIDIterator (break_id_t break_id)
{
    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
                        BreakpointIDMatches(break_id));             // Predicate
}

BreakpointList::bp_collection::const_iterator
BreakpointList::GetBreakpointIDConstIterator (break_id_t break_id) const
{
    return std::find_if(m_breakpoints.begin(), m_breakpoints.end(), // Search full range
                        BreakpointIDMatches(break_id));             // Predicate
}

BreakpointSP
BreakpointList::FindBreakpointByID (break_id_t break_id)
{
    Mutex::Locker locker(m_mutex);
    BreakpointSP stop_sp;
    bp_collection::iterator pos = GetBreakpointIDIterator(break_id);
    if (pos != m_breakpoints.end())
        stop_sp = *pos;

    return stop_sp;
}

const BreakpointSP
BreakpointList::FindBreakpointByID (break_id_t break_id) const
{
    Mutex::Locker locker(m_mutex);
    BreakpointSP stop_sp;
    bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id);
    if (pos != m_breakpoints.end())
        stop_sp = *pos;

    return stop_sp;
}

void
BreakpointList::Dump (Stream *s) const
{
    Mutex::Locker locker(m_mutex);
    s->Printf("%p: ", static_cast<const void*>(this));
    s->Indent();
    s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
    s->IndentMore();
    for (const auto &bp_sp : m_breakpoints)
        bp_sp->Dump(s);
    s->IndentLess();
}


BreakpointSP
BreakpointList::GetBreakpointAtIndex (size_t i)
{
    Mutex::Locker locker(m_mutex);
    BreakpointSP stop_sp;
    bp_collection::iterator end = m_breakpoints.end();
    bp_collection::iterator pos;
    size_t curr_i = 0;
    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
    {
        if (curr_i == i)
            stop_sp = *pos;
    }
    return stop_sp;
}

const BreakpointSP
BreakpointList::GetBreakpointAtIndex (size_t i) const
{
    Mutex::Locker locker(m_mutex);
    BreakpointSP stop_sp;
    bp_collection::const_iterator end = m_breakpoints.end();
    bp_collection::const_iterator pos;
    size_t curr_i = 0;
    for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
    {
        if (curr_i == i)
            stop_sp = *pos;
    }
    return stop_sp;
}

void
BreakpointList::UpdateBreakpoints (ModuleList& module_list, bool added, bool delete_locations)
{
    Mutex::Locker locker(m_mutex);
    for (const auto &bp_sp : m_breakpoints)
        bp_sp->ModulesChanged (module_list, added, delete_locations);

}

void
BreakpointList::UpdateBreakpointsWhenModuleIsReplaced (ModuleSP old_module_sp, ModuleSP new_module_sp)
{
    Mutex::Locker locker(m_mutex);
    for (const auto &bp_sp : m_breakpoints)
        bp_sp->ModuleReplaced (old_module_sp, new_module_sp);

}

void
BreakpointList::ClearAllBreakpointSites ()
{
    Mutex::Locker locker(m_mutex);
    for (const auto &bp_sp : m_breakpoints)
        bp_sp->ClearAllBreakpointSites ();

}

void
BreakpointList::GetListMutex (Mutex::Locker &locker)
{
    return locker.Lock (m_mutex);
}
