//===-- 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 (size_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 (size_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;
}

bool 
BreakpointLocationCollection::IsInternal () const
{
    collection::const_iterator pos,
        begin = m_break_loc_collection.begin(),
        end = m_break_loc_collection.end();

    bool is_internal = true;
    
    for (pos = begin; pos != end; ++pos)
    {
        if (!(*pos)->GetBreakpoint().IsInternal ())
        {
            is_internal = false;
            break;
        }
    }
    return is_internal;
}

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);
    }
}
