//===-- 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/Host/StringConvert.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 eTypeChar:
                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::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
    Args args(value.str().c_str());
    Error error = SetArgs (args, op);
    if (error.Success())
        NotifyValueChanged();
    return error;
}


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 = StringConvert::ToSInt32(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 = StringConvert::ToUInt32(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 =
                  StringConvert::ToSInt32(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 = StringConvert::ToUInt32(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
        LLVM_FALLTHROUGH;
    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);
    *static_cast<OptionValue *>(copied_array) = *this;
    copied_array->m_callback = m_callback;
    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;
}



