//===-- 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;
    size_t i = 0;
    size_t prev_size = GetSize();
    while (i < prev_size)
    {
        // ShouldStop can remove the breakpoint from the list
        if (GetByIndex(i)->ShouldStop(context))
            shouldStop = true;

        if (prev_size == GetSize())
            i++;
        prev_size = GetSize();
    }
    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);
    }
}

