//===-- BreakpointLocationCollection.cpp ------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// BreakpointLocationCollection constructor
//----------------------------------------------------------------------
BreakpointLocationCollection::BreakpointLocationCollection() :
    m_break_loc_collection()
{
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
BreakpointLocationCollection::~BreakpointLocationCollection()
{
}

void
BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc)
{
    BreakpointLocationSP old_bp_loc = FindByIDPair (bp_loc->GetBreakpoint().GetID(), bp_loc->GetID());
    if (!old_bp_loc.get())
        m_break_loc_collection.push_back(bp_loc);
}

bool
BreakpointLocationCollection::Remove (lldb::break_id_t bp_id, lldb::break_id_t bp_loc_id)
{
    collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id);    // Predicate
    if (pos != m_break_loc_collection.end())
    {
        m_break_loc_collection.erase(pos);
        return true;
    }
    return false;

}

class BreakpointIDPairMatches
{
public:
    BreakpointIDPairMatches (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) :
        m_break_id(break_id),
        m_break_loc_id (break_loc_id)
    {
    }

    bool operator() (const BreakpointLocationSP &bp_loc) const
    {
        return m_break_id == bp_loc->GetBreakpoint().GetID()
            && m_break_loc_id == bp_loc->GetID();
    }

private:
   const lldb::break_id_t m_break_id;
   const lldb::break_id_t m_break_loc_id;
};

BreakpointLocationCollection::collection::iterator
BreakpointLocationCollection::GetIDPairIterator (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
{
    return std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(),   // Search full range
                        BreakpointIDPairMatches(break_id, break_loc_id));               // Predicate
}

BreakpointLocationCollection::collection::const_iterator
BreakpointLocationCollection::GetIDPairConstIterator (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const
{
    return std::find_if(m_break_loc_collection.begin(), m_break_loc_collection.end(),   // Search full range
                        BreakpointIDPairMatches(break_id, break_loc_id));               // Predicate
}

BreakpointLocationSP
BreakpointLocationCollection::FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
{
    BreakpointLocationSP stop_sp;
    collection::iterator pos = GetIDPairIterator(break_id, break_loc_id);
    if (pos != m_break_loc_collection.end())
        stop_sp = *pos;

    return stop_sp;
}

const BreakpointLocationSP
BreakpointLocationCollection::FindByIDPair (lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const
{
    BreakpointLocationSP stop_sp;
    collection::const_iterator pos = GetIDPairConstIterator(break_id, break_loc_id);
    if (pos != m_break_loc_collection.end())
        stop_sp = *pos;

    return stop_sp;
}

BreakpointLocationSP
BreakpointLocationCollection::GetByIndex (uint32_t i)
{
    BreakpointLocationSP stop_sp;
    if (i < m_break_loc_collection.size())
        stop_sp = m_break_loc_collection[i];

    return stop_sp;
}

const BreakpointLocationSP
BreakpointLocationCollection::GetByIndex (uint32_t i) const
{
    BreakpointLocationSP stop_sp;
    if (i < m_break_loc_collection.size())
        stop_sp = m_break_loc_collection[i];

    return stop_sp;
}

bool
BreakpointLocationCollection::ShouldStop (StoppointCallbackContext *context)
{
    bool shouldStop = false;
    const size_t count = GetSize();
    for (size_t i = 0; i < count; i++) 
    {
        if (GetByIndex(i)->ShouldStop(context))
            shouldStop = true;
    }
    return shouldStop;
}

bool 
BreakpointLocationCollection::ValidForThisThread (Thread *thread)
{
    collection::iterator pos,
        begin = m_break_loc_collection.begin(),
        end = m_break_loc_collection.end();

    for (pos = begin; pos != end; ++pos)
    {
        if ((*pos)->ValidForThisThread (thread))
            return true;
    }
    return false;
}


void
BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    collection::iterator pos,
        begin = m_break_loc_collection.begin(),
        end = m_break_loc_collection.end();

    for (pos = begin; pos != end; ++pos)
    {
        if (pos != begin)
            s->PutChar(' ');
        (*pos)->GetDescription(s, level);
    }
}
