//===-- BreakpointSiteList.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/BreakpointSiteList.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
#include <algorithm>

using namespace lldb;
using namespace lldb_private;

BreakpointSiteList::BreakpointSiteList() : m_mutex(), m_bp_site_list()
{
}

BreakpointSiteList::~BreakpointSiteList()
{
}

// Add breakpoint site to the list.  However, if the element already exists in the
// list, then we don't add it, and return LLDB_INVALID_BREAK_ID.

lldb::break_id_t
BreakpointSiteList::Add(const BreakpointSiteSP &bp)
{
    lldb::addr_t bp_site_load_addr = bp->GetLoadAddress();
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    collection::iterator iter = m_bp_site_list.find (bp_site_load_addr);

    if (iter == m_bp_site_list.end())
    {
        m_bp_site_list.insert (iter, collection::value_type (bp_site_load_addr, bp));
        return bp->GetID();
    }
    else
    {
        return LLDB_INVALID_BREAK_ID;
    }
}

bool
BreakpointSiteList::ShouldStop (StoppointCallbackContext *context, lldb::break_id_t site_id)
{
    BreakpointSiteSP site_sp (FindByID (site_id));
    if (site_sp)
    {
        // Let the BreakpointSite decide if it should stop here (could not have
        // reached it's target hit count yet, or it could have a callback
        // that decided it shouldn't stop (shared library loads/unloads).
        return site_sp->ShouldStop (context);
    }
    // We should stop here since this BreakpointSite isn't valid anymore or it
    // doesn't exist.
    return true;
}
lldb::break_id_t
BreakpointSiteList::FindIDByAddress (lldb::addr_t addr)
{
    BreakpointSiteSP bp = FindByAddress (addr);
    if (bp)
    {
        //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8" PRIx64 " ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID());
        return bp.get()->GetID();
    }
    //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8" PRIx64 " ) => NONE", __FUNCTION__, (uint64_t)addr);
    return LLDB_INVALID_BREAK_ID;
}

bool
BreakpointSiteList::Remove (lldb::break_id_t break_id)
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    collection::iterator pos = GetIDIterator(break_id);    // Predicate
    if (pos != m_bp_site_list.end())
    {
        m_bp_site_list.erase(pos);
        return true;
    }
    return false;
}

bool
BreakpointSiteList::RemoveByAddress (lldb::addr_t address)
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    collection::iterator pos =  m_bp_site_list.find(address);
    if (pos != m_bp_site_list.end())
    {
        m_bp_site_list.erase(pos);
        return true;
    }
    return false;
}

class BreakpointSiteIDMatches
{
public:
    BreakpointSiteIDMatches (lldb::break_id_t break_id) :
        m_break_id(break_id)
    {
    }

    bool operator() (std::pair <lldb::addr_t, BreakpointSiteSP> val_pair) const
    {
        return m_break_id == val_pair.second.get()->GetID();
    }

private:
   const lldb::break_id_t m_break_id;
};

BreakpointSiteList::collection::iterator
BreakpointSiteList::GetIDIterator (lldb::break_id_t break_id)
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(),   // Search full range
                        BreakpointSiteIDMatches(break_id));             // Predicate
}

BreakpointSiteList::collection::const_iterator
BreakpointSiteList::GetIDConstIterator (lldb::break_id_t break_id) const
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    return std::find_if(m_bp_site_list.begin(), m_bp_site_list.end(),   // Search full range
                        BreakpointSiteIDMatches(break_id));             // Predicate
}

BreakpointSiteSP
BreakpointSiteList::FindByID (lldb::break_id_t break_id)
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    BreakpointSiteSP stop_sp;
    collection::iterator pos = GetIDIterator(break_id);
    if (pos != m_bp_site_list.end())
        stop_sp = pos->second;

    return stop_sp;
}

const BreakpointSiteSP
BreakpointSiteList::FindByID (lldb::break_id_t break_id) const
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    BreakpointSiteSP stop_sp;
    collection::const_iterator pos = GetIDConstIterator(break_id);
    if (pos != m_bp_site_list.end())
        stop_sp = pos->second;

    return stop_sp;
}

BreakpointSiteSP
BreakpointSiteList::FindByAddress (lldb::addr_t addr)
{
    BreakpointSiteSP found_sp;
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    collection::iterator iter =  m_bp_site_list.find(addr);
    if (iter != m_bp_site_list.end())
        found_sp = iter->second;
    return found_sp;
}

bool
BreakpointSiteList::BreakpointSiteContainsBreakpoint (lldb::break_id_t bp_site_id, lldb::break_id_t bp_id)
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    collection::const_iterator pos = GetIDConstIterator(bp_site_id);
    if (pos != m_bp_site_list.end())
        return pos->second->IsBreakpointAtThisSite (bp_id);

    return false;
}

void
BreakpointSiteList::Dump (Stream *s) const
{
    s->Printf("%p: ", static_cast<const void*>(this));
    //s->Indent();
    s->Printf("BreakpointSiteList with %u BreakpointSites:\n", (uint32_t)m_bp_site_list.size());
    s->IndentMore();
    collection::const_iterator pos;
    collection::const_iterator end = m_bp_site_list.end();
    for (pos = m_bp_site_list.begin(); pos != end; ++pos)
        pos->second.get()->Dump(s);
    s->IndentLess();
}

void
BreakpointSiteList::ForEach (std::function <void(BreakpointSite *)> const &callback)
{
    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    for (auto pair : m_bp_site_list)
        callback (pair.second.get());
}

bool
BreakpointSiteList::FindInRange (lldb::addr_t lower_bound, lldb::addr_t upper_bound, BreakpointSiteList &bp_site_list) const
{
    if (lower_bound > upper_bound)
        return false;

    std::lock_guard<std::recursive_mutex> guard(m_mutex);
    collection::const_iterator lower, upper, pos;
    lower = m_bp_site_list.lower_bound(lower_bound);
    if (lower == m_bp_site_list.end()
            || (*lower).first >= upper_bound)
        return false;
    
    // This is one tricky bit.  The breakpoint might overlap the bottom end of the range.  So we grab the
    // breakpoint prior to the lower bound, and check that that + its byte size isn't in our range.
    if (lower != m_bp_site_list.begin())
    {
        collection::const_iterator prev_pos = lower;
        prev_pos--;
        const BreakpointSiteSP &prev_bp = (*prev_pos).second;
        if (prev_bp->GetLoadAddress() + prev_bp->GetByteSize() > lower_bound)
            bp_site_list.Add (prev_bp);
        
    }
    
    upper = m_bp_site_list.upper_bound(upper_bound);
        
    for (pos = lower; pos != upper; pos++)
    {
        bp_site_list.Add ((*pos).second);
    }
    return true;
}
