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

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Stream.h"
#include "lldb/Interpreter/Args.h"

using namespace lldb;
using namespace lldb_private;

void
OptionValueArray::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
{
    const Type array_element_type = ConvertTypeMaskToType (m_type_mask);
    if (dump_mask & eDumpOptionType)
    {
        if ((GetType() == eTypeArray) && (m_type_mask != eTypeInvalid))
            strm.Printf ("(%s of %ss)", GetTypeAsCString(), GetBuiltinTypeAsCString(array_element_type));
        else
            strm.Printf ("(%s)", GetTypeAsCString());
    }
    if (dump_mask & eDumpOptionValue)
    {
        if (dump_mask & eDumpOptionType)
            strm.Printf (" =%s", (m_values.size() > 0) ? "\n" : "");
        strm.IndentMore();
        const uint32_t size = m_values.size();
        for (uint32_t i = 0; i<size; ++i)
        {
            strm.Indent();
            strm.Printf("[%u]: ", i);
            const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0;
            switch (array_element_type)
            {
                default:
                case eTypeArray:
                case eTypeDictionary:
                case eTypeProperties:
                case eTypeFileSpecList:
                case eTypePathMap:
                    m_values[i]->DumpValue(exe_ctx, strm, dump_mask | extra_dump_options);
                    break;
                    
                case eTypeBoolean:
                case eTypeEnum:
                case eTypeFileSpec:
                case eTypeFormat:
                case eTypeSInt64:
                case eTypeString:
                case eTypeUInt64:
                case eTypeUUID:
                    // No need to show the type for dictionaries of simple items
                    m_values[i]->DumpValue(exe_ctx, strm, (dump_mask & (~eDumpOptionType)) | extra_dump_options);
                    break;
            }
            if (i < (size - 1))
                strm.EOL();
        }
        strm.IndentLess();
    }
}

Error
OptionValueArray::SetValueFromCString (const char *value, VarSetOperationType op)
{
    Args args(value);
    return SetArgs (args, op);
}


lldb::OptionValueSP
OptionValueArray::GetSubValue (const ExecutionContext *exe_ctx,
                               const char *name,
                               bool will_modify,
                               Error &error) const
{
    if (name && name[0] == '[')
    {
        const char *end_bracket = strchr (name+1, ']');
        if (end_bracket)
        {
            const char *sub_value = nullptr;
            if (end_bracket[1])
                sub_value = end_bracket + 1;
            std::string index_str (name+1, end_bracket);
            const size_t array_count = m_values.size();
            int32_t idx = Args::StringToSInt32(index_str.c_str(), INT32_MAX, 0, nullptr);
            if (idx != INT32_MAX)
            {
                ;
                uint32_t new_idx = UINT32_MAX;
                if (idx < 0)
                {
                    // Access from the end of the array if the index is negative
                    new_idx = array_count - idx;
                }
                else
                {
                    // Just a standard index
                    new_idx = idx;
                }

                if (new_idx < array_count)
                {
                    if (m_values[new_idx])
                    {
                        if (sub_value)
                            return m_values[new_idx]->GetSubValue (exe_ctx, sub_value, will_modify, error);
                        else
                            return m_values[new_idx];
                    }
                }
                else
                {
                    if (array_count == 0)
                        error.SetErrorStringWithFormat("index %i is not valid for an empty array", idx);
                    else if (idx > 0)
                        error.SetErrorStringWithFormat("index %i out of range, valid values are 0 through %" PRIu64, idx, (uint64_t)(array_count - 1));
                    else
                        error.SetErrorStringWithFormat("negative index %i out of range, valid values are -1 through -%" PRIu64, idx, (uint64_t)array_count);
                }
            }
        }
    }
    else
    {
        error.SetErrorStringWithFormat("invalid value path '%s', %s values only support '[<index>]' subvalues where <index> is a positive or negative array index", name, GetTypeAsCString());
    }
    return OptionValueSP();
}


size_t
OptionValueArray::GetArgs (Args &args) const
{
    const uint32_t size = m_values.size();
    std::vector<const char *> argv;
    for (uint32_t i = 0; i<size; ++i)
    {
        const char *string_value = m_values[i]->GetStringValue ();
        if (string_value)
            argv.push_back(string_value);
    }
    
    if (argv.empty())
        args.Clear();
    else
        args.SetArguments(argv.size(), &argv[0]);
    return args.GetArgumentCount();
}

Error
OptionValueArray::SetArgs (const Args &args, VarSetOperationType op)
{
    Error error;
    const size_t argc = args.GetArgumentCount();
    switch (op)
    {
    case eVarSetOperationInvalid:
        error.SetErrorString("unsupported operation");
        break;
        
    case eVarSetOperationInsertBefore:
    case eVarSetOperationInsertAfter:
        if (argc > 1)
        {
            uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
            const uint32_t count = GetSize();
            if (idx > count)
            {
                error.SetErrorStringWithFormat("invalid insert array index %u, index must be 0 through %u", idx, count);
            }
            else
            {
                if (op == eVarSetOperationInsertAfter)
                    ++idx;
                for (size_t i=1; i<argc; ++i, ++idx)
                {
                    lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i),
                                                                                     m_type_mask,
                                                                                     error));
                    if (value_sp)
                    {
                        if (error.Fail())
                            return error;
                        if (idx >= m_values.size())
                            m_values.push_back(value_sp);
                        else
                            m_values.insert(m_values.begin() + idx, value_sp);
                    }
                    else
                    {
                        error.SetErrorString("array of complex types must subclass OptionValueArray");
                        return error;
                    }
                }
            }
        }
        else
        {
            error.SetErrorString("insert operation takes an array index followed by one or more values");
        }
        break;
        
    case eVarSetOperationRemove:
        if (argc > 0)
        {
            const uint32_t size = m_values.size();
            std::vector<int> remove_indexes;
            bool all_indexes_valid = true;
            size_t i;
            for (i=0; i<argc; ++i)
            {
                const size_t idx =
                  Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX);
                if (idx >= size)
                {
                    all_indexes_valid = false;
                    break;
                }
                else
                    remove_indexes.push_back(idx);
            }
            
            if (all_indexes_valid)
            {
                size_t num_remove_indexes = remove_indexes.size();
                if (num_remove_indexes)
                {
                    // Sort and then erase in reverse so indexes are always valid
                    if (num_remove_indexes > 1)
                    {
                        std::sort(remove_indexes.begin(), remove_indexes.end());
                        for (std::vector<int>::const_reverse_iterator pos = remove_indexes.rbegin(), end = remove_indexes.rend(); pos != end; ++pos)
                        {
                            m_values.erase(m_values.begin() + *pos);
                        }
                    }
                    else
                    {
                        // Only one index
                        m_values.erase(m_values.begin() + remove_indexes.front());
                    }
                }
            }
            else
            {
                error.SetErrorStringWithFormat("invalid array index '%s', aborting remove operation", args.GetArgumentAtIndex(i));
            }
        }
        else
        {
            error.SetErrorString("remove operation takes one or more array indices");
        }
        break;
        
    case eVarSetOperationClear:
        Clear ();
        break;
        
    case eVarSetOperationReplace:
        if (argc > 1)
        {
            uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX);
            const uint32_t count = GetSize();
            if (idx > count)
            {
                error.SetErrorStringWithFormat("invalid replace array index %u, index must be 0 through %u", idx, count);
            }
            else
            {
                for (size_t i=1; i<argc; ++i, ++idx)
                {
                    lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i),
                                                                                     m_type_mask,
                                                                                     error));
                    if (value_sp)
                    {
                        if (error.Fail())
                            return error;
                        if (idx < count)
                            m_values[idx] = value_sp;
                        else
                            m_values.push_back(value_sp);
                    }
                    else
                    {
                        error.SetErrorString("array of complex types must subclass OptionValueArray");
                        return error;
                    }
                }
            }
        }
        else
        {
            error.SetErrorString("replace operation takes an array index followed by one or more values");
        }
        break;
        
    case eVarSetOperationAssign:
        m_values.clear();
        // Fall through to append case
    case eVarSetOperationAppend:
        for (size_t i=0; i<argc; ++i)
        {
            lldb::OptionValueSP value_sp (CreateValueFromCStringForTypeMask (args.GetArgumentAtIndex(i),
                                                                             m_type_mask,
                                                                             error));
            if (value_sp)
            {
                if (error.Fail())
                    return error;
                m_value_was_set = true;
                AppendValue(value_sp);
            }
            else
            {
                error.SetErrorString("array of complex types must subclass OptionValueArray");
            }
        }
        break;
    }
    return error;
}

lldb::OptionValueSP
OptionValueArray::DeepCopy () const
{
    OptionValueArray *copied_array = new OptionValueArray (m_type_mask, m_raw_value_dump);
    lldb::OptionValueSP copied_value_sp(copied_array);
    const uint32_t size = m_values.size();
    for (uint32_t i = 0; i<size; ++i)
    {
        copied_array->AppendValue (m_values[i]->DeepCopy());
    }
    return copied_value_sp;
}



