//===-- 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, 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();

    for (size_t i = 0; i < num_old_args; ++i)
    {
        bool is_range = false;
        current_arg = old_args.GetArgumentAtIndex (i);

        size_t range_start_len = 0;
        size_t range_end_pos = 0;
        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 ((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);
        }
    }

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