//===-- 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::SetEnabledAll (bool enabled)
{
    Mutex::Locker locker(m_mutex);
    bp_collection::iterator pos, end = m_breakpoints.end();
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        (*pos)->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: ", (int)sizeof(void*) * 2, this);
    s->Indent();
    s->Printf("BreakpointList with %u Breakpoints:\n", (uint32_t)m_breakpoints.size());
    s->IndentMore();
    bp_collection::const_iterator pos;
    bp_collection::const_iterator end = m_breakpoints.end();
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        (*pos)->Dump(s);
    s->IndentLess();
}


BreakpointSP
BreakpointList::GetBreakpointAtIndex (uint32_t i)
{
    Mutex::Locker locker(m_mutex);
    BreakpointSP stop_sp;
    bp_collection::iterator end = m_breakpoints.end();
    bp_collection::iterator pos;
    uint32_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 (uint32_t i) const
{
    Mutex::Locker locker(m_mutex);
    BreakpointSP stop_sp;
    bp_collection::const_iterator end = m_breakpoints.end();
    bp_collection::const_iterator pos;
    uint32_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)
{
    Mutex::Locker locker(m_mutex);
    bp_collection::iterator end = m_breakpoints.end();
    bp_collection::iterator pos;
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        (*pos)->ModulesChanged (module_list, added);

}

void
BreakpointList::ClearAllBreakpointSites ()
{
    Mutex::Locker locker(m_mutex);
    bp_collection::iterator end = m_breakpoints.end();
    bp_collection::iterator pos;
    for (pos = m_breakpoints.begin(); pos != end; ++pos)
        (*pos)->ClearAllBreakpointSites ();

}

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