//===-- 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/Breakpoint/BreakpointLocationList.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);
    }
}
