//===-- 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 (uint32_t index)
{
    if (index < m_breakpoint_ids.size())
        return m_breakpoint_ids[index];
    else
        return m_invalid_id;
}

bool
BreakpointIDList::RemoveBreakpointIDAtIndex (uint32_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, uint32_t *position)
{
    bool success = false;
    BreakpointIDArray::iterator tmp_pos;

    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())
        {
            success = true;
            *position = i;
            return true;
        }
    }

    return false;
}

bool
BreakpointIDList::FindBreakpointID (const char *bp_id_str, uint32_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, uint32_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);

        uint32_t range_start_len = 0;
        uint32_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, 
                                                   uint32_t *range_start_len, 
                                                   uint32_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];
        int 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;
}
