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

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

//----------------------------------------------------------------------
// class BreakpointIDList
//----------------------------------------------------------------------

BreakpointIDList::BreakpointIDList () :
m_invalid_id (LLDB_INVALID_BREAK_ID, LLDB_INVALID_BREAK_ID)
{
}

BreakpointIDList::~BreakpointIDList ()
{
}

size_t
BreakpointIDList::GetSize()
{
    return m_breakpoint_ids.size();
}

BreakpointID &
BreakpointIDList::GetBreakpointIDAtIndex (size_t index)
{
    if (index < m_breakpoint_ids.size())
        return m_breakpoint_ids[index];
    else
        return m_invalid_id;
}

bool
BreakpointIDList::RemoveBreakpointIDAtIndex (size_t index)
{
    if (index >= m_breakpoint_ids.size())
        return false;

    m_breakpoint_ids.erase (m_breakpoint_ids.begin() + index);
    return true;
}

void
BreakpointIDList::Clear()
{
    m_breakpoint_ids.clear ();
}

bool
BreakpointIDList::AddBreakpointID (BreakpointID bp_id)
{
    m_breakpoint_ids.push_back (bp_id);

    return true;  // We don't do any verification in this function, so always return true.
}

bool
BreakpointIDList::AddBreakpointID (const char *bp_id_str)
{
    BreakpointID temp_bp_id;
    break_id_t bp_id;
    break_id_t loc_id;

    bool success = BreakpointID::ParseCanonicalReference (bp_id_str, &bp_id, &loc_id);

    if (success)
    {
        temp_bp_id.SetID (bp_id, loc_id);
        m_breakpoint_ids.push_back (temp_bp_id);
    }

    return success;
}

bool
BreakpointIDList::FindBreakpointID (BreakpointID &bp_id, size_t *position)
{
    for (size_t i = 0; i < m_breakpoint_ids.size(); ++i)
    {
        BreakpointID tmp_id = m_breakpoint_ids[i];
        if (tmp_id.GetBreakpointID() == bp_id.GetBreakpointID()
            && tmp_id.GetLocationID() == bp_id.GetLocationID())
        {
            *position = i;
            return true;
        }
    }

    return false;
}

bool
BreakpointIDList::FindBreakpointID (const char *bp_id_str, size_t *position)
{
    BreakpointID temp_bp_id;
    break_id_t bp_id;
    break_id_t loc_id;

    if (BreakpointID::ParseCanonicalReference (bp_id_str, &bp_id, &loc_id))
    {
        temp_bp_id.SetID (bp_id, loc_id);
        return FindBreakpointID (temp_bp_id, position);
    }
    else
        return false;
}

void
BreakpointIDList::InsertStringArray (const char **string_array, size_t array_size, CommandReturnObject &result)
{
    if (string_array == NULL)
        return;

    for (uint32_t i = 0; i < array_size; ++i)
    {
        break_id_t bp_id;
        break_id_t loc_id;

        if (BreakpointID::ParseCanonicalReference (string_array[i], &bp_id, &loc_id))
        {
            if (bp_id != LLDB_INVALID_BREAK_ID)
            {
                BreakpointID temp_bp_id(bp_id, loc_id);
                m_breakpoint_ids.push_back (temp_bp_id);
            }
            else
            {
                result.AppendErrorWithFormat ("'%s' is not a valid breakpoint ID.\n", string_array[i]);
                result.SetStatus (eReturnStatusFailed);
                return;
            }
        }
    }
    result.SetStatus (eReturnStatusSuccessFinishNoResult);
}


//  This function takes OLD_ARGS, which is usually the result of breaking the command string arguments into
//  an array of space-separated strings, and searches through the arguments for any breakpoint ID range specifiers.
//  Any string in the array that is not part of an ID range specifier is copied directly into NEW_ARGS.  If any
//  ID range specifiers are found, the range is interpreted and a list of canonical breakpoint IDs corresponding to
//  all the current breakpoints and locations in the range are added to NEW_ARGS.  When this function is done,
//  NEW_ARGS should be a copy of OLD_ARGS, with and ID range specifiers replaced by the members of the range.

void
BreakpointIDList::FindAndReplaceIDRanges (Args &old_args,
                                          Target *target,
                                          bool allow_locations,
                                          CommandReturnObject &result,
                                          Args &new_args)
{
    std::string range_start;
    const char *range_end;
    const char *current_arg;
    const size_t num_old_args = old_args.GetArgumentCount();
    std::set<std::string> names_found;

    for (size_t i = 0; i < num_old_args; ++i)
    {
        bool is_range = false;

        current_arg = old_args.GetArgumentAtIndex (i);
        if (!allow_locations && strchr(current_arg, '.') != nullptr)
        {
            result.AppendErrorWithFormat ("Breakpoint locations not allowed, saw location: %s.", current_arg);
            new_args.Clear();
            return;
        }

        size_t range_start_len = 0;
        size_t range_end_pos = 0;
        Error error;

        if (BreakpointIDList::StringContainsIDRangeExpression (current_arg, &range_start_len, &range_end_pos))
        {
            is_range = true;
            range_start.assign (current_arg, range_start_len);
            range_end = current_arg + range_end_pos;
        }
        else if (BreakpointID::StringIsBreakpointName(current_arg, error))
        {
            if (!error.Success())
            {
                new_args.Clear();
                result.AppendError (error.AsCString());
                result.SetStatus (eReturnStatusFailed);
                return;
            }
            else
                names_found.insert(current_arg);
        }
        else if ((i + 2 < num_old_args)
                 && BreakpointID::IsRangeIdentifier (old_args.GetArgumentAtIndex (i+1))
                 && BreakpointID::IsValidIDExpression (current_arg)
                 && BreakpointID::IsValidIDExpression (old_args.GetArgumentAtIndex (i+2)))
        {
            range_start.assign (current_arg);
            range_end = old_args.GetArgumentAtIndex (i+2);
            is_range = true;
            i = i+2;
        }
        else
        {
            // See if user has specified id.*
            std::string tmp_str = old_args.GetArgumentAtIndex (i);
            size_t pos = tmp_str.find ('.');
            if (pos != std::string::npos)
            {
                std::string bp_id_str = tmp_str.substr (0, pos);
                if (BreakpointID::IsValidIDExpression (bp_id_str.c_str())
                    && tmp_str[pos+1] == '*'
                    && tmp_str.length() == (pos + 2))
                {
                    break_id_t bp_id;
                    break_id_t bp_loc_id;

                    BreakpointID::ParseCanonicalReference (bp_id_str.c_str(), &bp_id, &bp_loc_id);
                    BreakpointSP breakpoint_sp = target->GetBreakpointByID (bp_id);
                    if (! breakpoint_sp)
                    {
                        new_args.Clear();
                        result.AppendErrorWithFormat ("'%d' is not a valid breakpoint ID.\n", bp_id);
                        result.SetStatus (eReturnStatusFailed);
                        return;
                    }
                    const size_t num_locations = breakpoint_sp->GetNumLocations();
                    for (size_t j = 0; j < num_locations; ++j)
                    {
                        BreakpointLocation *bp_loc = breakpoint_sp->GetLocationAtIndex(j).get();
                        StreamString canonical_id_str;
                        BreakpointID::GetCanonicalReference (&canonical_id_str, bp_id, bp_loc->GetID());
                        new_args.AppendArgument (canonical_id_str.GetData());
                    }
                }
                
            }
        }

        if (is_range)
        {
            break_id_t start_bp_id;
            break_id_t end_bp_id;
            break_id_t start_loc_id;
            break_id_t end_loc_id;

            BreakpointID::ParseCanonicalReference (range_start.c_str(), &start_bp_id, &start_loc_id);
            BreakpointID::ParseCanonicalReference (range_end, &end_bp_id, &end_loc_id);

            if ((start_bp_id == LLDB_INVALID_BREAK_ID)
                || (! target->GetBreakpointByID (start_bp_id)))
            {
                new_args.Clear();
                result.AppendErrorWithFormat ("'%s' is not a valid breakpoint ID.\n", range_start.c_str());
                result.SetStatus (eReturnStatusFailed);
                return;
            }

            if ((end_bp_id == LLDB_INVALID_BREAK_ID)
                || (! target->GetBreakpointByID (end_bp_id)))
            {
                new_args.Clear();
                result.AppendErrorWithFormat ("'%s' is not a valid breakpoint ID.\n", range_end);
                result.SetStatus (eReturnStatusFailed);
                return;
            }
            

            if (((start_loc_id == LLDB_INVALID_BREAK_ID)
                 && (end_loc_id != LLDB_INVALID_BREAK_ID))
                || ((start_loc_id != LLDB_INVALID_BREAK_ID)
                    && (end_loc_id == LLDB_INVALID_BREAK_ID)))
            {
                new_args.Clear ();
                result.AppendErrorWithFormat ("Invalid breakpoint id range:  Either both ends of range must specify"
                                              " a breakpoint location, or neither can specify a breakpoint location.\n");
                result.SetStatus (eReturnStatusFailed);
                return;
            }

            // We have valid range starting & ending breakpoint IDs.  Go through all the breakpoints in the
            // target and find all the breakpoints that fit into this range, and add them to new_args.
            
            // Next check to see if we have location id's.  If so, make sure the start_bp_id and end_bp_id are
            // for the same breakpoint; otherwise we have an illegal range: breakpoint id ranges that specify
            // bp locations are NOT allowed to cross major bp id numbers.
            
            if  ((start_loc_id != LLDB_INVALID_BREAK_ID)
                || (end_loc_id != LLDB_INVALID_BREAK_ID))
            {
                if (start_bp_id != end_bp_id)
                {
                    new_args.Clear();
                    result.AppendErrorWithFormat ("Invalid range: Ranges that specify particular breakpoint locations"
                                                  " must be within the same major breakpoint; you specified two"
                                                  " different major breakpoints, %d and %d.\n", 
                                                  start_bp_id, end_bp_id);
                    result.SetStatus (eReturnStatusFailed);
                    return;
                }
            }

            const BreakpointList& breakpoints = target->GetBreakpointList();
            const size_t num_breakpoints = breakpoints.GetSize();
            for (size_t j = 0; j < num_breakpoints; ++j)
            {
                Breakpoint *breakpoint = breakpoints.GetBreakpointAtIndex (j).get();
                break_id_t cur_bp_id = breakpoint->GetID();

                if ((cur_bp_id < start_bp_id) || (cur_bp_id > end_bp_id))
                    continue;

                const size_t num_locations = breakpoint->GetNumLocations();

                if ((cur_bp_id == start_bp_id) && (start_loc_id != LLDB_INVALID_BREAK_ID))
                {
                    for (size_t k = 0; k < num_locations; ++k)
                    {
                        BreakpointLocation * bp_loc = breakpoint->GetLocationAtIndex(k).get();
                        if ((bp_loc->GetID() >= start_loc_id) && (bp_loc->GetID() <= end_loc_id))
                        {
                            StreamString canonical_id_str;
                            BreakpointID::GetCanonicalReference (&canonical_id_str, cur_bp_id, bp_loc->GetID());
                            new_args.AppendArgument (canonical_id_str.GetData());
                        }
                    }
                }
                else if ((cur_bp_id == end_bp_id) && (end_loc_id != LLDB_INVALID_BREAK_ID))
                {
                    for (size_t k = 0; k < num_locations; ++k)
                    {
                        BreakpointLocation * bp_loc = breakpoint->GetLocationAtIndex(k).get();
                        if (bp_loc->GetID() <= end_loc_id)
                        {
                            StreamString canonical_id_str;
                            BreakpointID::GetCanonicalReference (&canonical_id_str, cur_bp_id, bp_loc->GetID());
                            new_args.AppendArgument (canonical_id_str.GetData());
                        }
                    }
                }
                else
                {
                    StreamString canonical_id_str;
                    BreakpointID::GetCanonicalReference (&canonical_id_str, cur_bp_id, LLDB_INVALID_BREAK_ID);
                    new_args.AppendArgument (canonical_id_str.GetData());
                }
            }
        }
        else  // else is_range was false
        {
            new_args.AppendArgument (current_arg);
        }
    }

    // Okay, now see if we found any names, and if we did, add them:
    if (target && names_found.size())
    {
        for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints())
        {
            for (std::string name : names_found)
            {
                if (bkpt_sp->MatchesName(name.c_str()))
                {
                    StreamString canonical_id_str;
                    BreakpointID::GetCanonicalReference (&canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
                    new_args.AppendArgument (canonical_id_str.GetData());
                }
            }
        }
    }

    result.SetStatus (eReturnStatusSuccessFinishNoResult);
    return;
}

bool
BreakpointIDList::StringContainsIDRangeExpression (const char *in_string, 
                                                   size_t *range_start_len,
                                                   size_t *range_end_pos)
{
    bool is_range_expression = false;
    std::string arg_str = in_string;
    std::string::size_type idx;
    std::string::size_type start_pos = 0;

    *range_start_len = 0;
    *range_end_pos = 0;

    int specifiers_size = 0;
    for (int i = 0; BreakpointID::g_range_specifiers[i] != NULL; ++i)
        ++specifiers_size;

    for (int i = 0; i < specifiers_size && !is_range_expression; ++i)
    {
        const char *specifier_str = BreakpointID::g_range_specifiers[i];
        size_t len = strlen (specifier_str);
        idx = arg_str.find (BreakpointID::g_range_specifiers[i]);
        if (idx != std::string::npos)
        {
            *range_start_len = idx - start_pos;
            std::string start_str = arg_str.substr (start_pos, *range_start_len);
            if (idx + len < arg_str.length())
            {
                *range_end_pos = idx + len;
                std::string end_str = arg_str.substr (*range_end_pos);
                if (BreakpointID::IsValidIDExpression (start_str.c_str())
                    && BreakpointID::IsValidIDExpression (end_str.c_str()))
                {
                    is_range_expression = true;
                    //*range_start = start_str;
                    //*range_end = end_str;
                }
            }
        }
    }

    if (!is_range_expression)
    {
        *range_start_len = 0;
        *range_end_pos = 0;
    }

    return is_range_expression;
}
