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

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

using namespace lldb;
using namespace lldb_private;


OptionValueProperties::OptionValueProperties (const ConstString &name) :
    OptionValue (),
    m_name (name),
    m_properties (),
    m_name_to_index ()
{
}

OptionValueProperties::OptionValueProperties (const OptionValueProperties &global_properties) :
    OptionValue (global_properties),
    std::enable_shared_from_this<OptionValueProperties> (),
    m_name (global_properties.m_name),
    m_properties (global_properties.m_properties),
    m_name_to_index (global_properties.m_name_to_index)
{
    // We now have an exact copy of "global_properties". We need to now
    // find all non-global settings and copy the property values so that
    // all non-global settings get new OptionValue instances created for
    // them.
    const size_t num_properties = m_properties.size();
    for (size_t i=0; i<num_properties; ++i)
    {
        // Duplicate any values that are not global when constructing properties from
        // a global copy
        if (m_properties[i].IsGlobal() == false)
        {
            lldb::OptionValueSP new_value_sp (m_properties[i].GetValue()->DeepCopy());
            m_properties[i].SetOptionValue(new_value_sp);
        }
    }
}



size_t
OptionValueProperties::GetNumProperties() const
{
    return m_properties.size();
}


void
OptionValueProperties::Initialize (const PropertyDefinition *defs)
{
    for (size_t i=0; defs[i].name; ++i)
    {
        Property property(defs[i]);
        assert(property.IsValid());
        m_name_to_index.Append(property.GetName().GetCString(),m_properties.size());
        property.GetValue()->SetParent(shared_from_this());
        m_properties.push_back(property);
    }
    m_name_to_index.Sort();
}

void
OptionValueProperties::SetValueChangedCallback (uint32_t property_idx,
                                                OptionValueChangedCallback callback,
                                                void *baton)
{
    Property *property = ProtectedGetPropertyAtIndex (property_idx);
    if (property)
        property->SetValueChangedCallback (callback, baton);
}

void
OptionValueProperties::AppendProperty(const ConstString &name,
                                      const ConstString &desc,
                                      bool is_global,
                                      const OptionValueSP &value_sp)
{
    Property property(name, desc, is_global, value_sp);
    m_name_to_index.Append(name.GetCString(),m_properties.size());
    m_properties.push_back(property);
    value_sp->SetParent (shared_from_this());
    m_name_to_index.Sort();
}



//bool
//OptionValueProperties::GetQualifiedName (Stream &strm)
//{
//    bool dumped_something = false;
////    lldb::OptionValuePropertiesSP parent_sp(GetParent ());
////    if (parent_sp)
////    {
////        parent_sp->GetQualifiedName (strm);
////        strm.PutChar('.');
////        dumped_something = true;
////    }
//    if (m_name)
//    {
//        strm << m_name;
//        dumped_something = true;
//    }
//    return dumped_something;
//}
//
lldb::OptionValueSP
OptionValueProperties::GetValueForKey  (const ExecutionContext *exe_ctx,
                                        const ConstString &key,
                                        bool will_modify) const
{
    lldb::OptionValueSP value_sp;
    size_t idx = m_name_to_index.Find (key.GetCString(), SIZE_MAX);
    if (idx < m_properties.size())
        value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
    return value_sp;
}

lldb::OptionValueSP
OptionValueProperties::GetSubValue (const ExecutionContext *exe_ctx,
                                    const char *name,
                                    bool will_modify,
                                    Error &error) const
{
    lldb::OptionValueSP value_sp;
    
    if (name && name[0])
    {
        const char *sub_name = nullptr;
        ConstString key;
        size_t key_len = ::strcspn (name, ".[{");
        
        if (name[key_len])
        {
            key.SetCStringWithLength (name, key_len);
            sub_name = name + key_len;
        }
        else
            key.SetCString (name);
        
        value_sp = GetValueForKey (exe_ctx, key, will_modify);
        if (sub_name && value_sp)
        {
            switch (sub_name[0])
            {
            case '.':
                return value_sp->GetSubValue (exe_ctx, sub_name + 1, will_modify, error);
            
            case '{':
                // Predicate matching for predicates like
                // "<setting-name>{<predicate>}"
                // strings are parsed by the current OptionValueProperties subclass
                // to mean whatever they want to. For instance a subclass of
                // OptionValueProperties for a lldb_private::Target might implement:
                // "target.run-args{arch==i386}"   -- only set run args if the arch is i386
                // "target.run-args{path=/tmp/a/b/c/a.out}" -- only set run args if the path matches
                // "target.run-args{basename==test&&arch==x86_64}" -- only set run args if executable basename is "test" and arch is "x86_64"
                if (sub_name[1])
                {
                    const char *predicate_start = sub_name + 1;
                    const char *predicate_end = strchr(predicate_start, '}');
                    if (predicate_end)
                    {
                        std::string predicate(predicate_start, predicate_end);
                        if (PredicateMatches(exe_ctx, predicate.c_str()))
                        {
                            if (predicate_end[1])
                            {
                                // Still more subvalue string to evaluate
                                return value_sp->GetSubValue (exe_ctx, predicate_end + 1, will_modify, error);
                            }
                            else
                            {
                                // We have a match!
                                break;
                            }
                        }
                    }
                }
                // Predicate didn't match or wasn't correctly formed
                value_sp.reset();
                break;
            
            case '[':
                // Array or dictionary access for subvalues like:
                // "[12]"       -- access 12th array element
                // "['hello']"  -- dictionary access of key named hello
                return value_sp->GetSubValue (exe_ctx, sub_name, will_modify, error);

            default:
                value_sp.reset();
                break;
            }
        }
    }
    return value_sp;
}

Error
OptionValueProperties::SetSubValue (const ExecutionContext *exe_ctx,
                                    VarSetOperationType op,
                                    const char *name,
                                    const char *value)
{
    Error error;
    const bool will_modify = true;
    lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, name, will_modify, error));
    if (value_sp)
        error = value_sp->SetValueFromString(value ? llvm::StringRef(value) : llvm::StringRef(), op);
    else
    {
        if (error.AsCString() == nullptr)
            error.SetErrorStringWithFormat("invalid value path '%s'", name);
    }
    return error;
}


ConstString
OptionValueProperties::GetPropertyNameAtIndex (uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex(nullptr, false, idx);
    if (property)
        return property->GetName();
    return ConstString();
    
}

const char *
OptionValueProperties::GetPropertyDescriptionAtIndex (uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex(nullptr, false, idx);
    if (property)
        return property->GetDescription();
    return nullptr;
}

uint32_t
OptionValueProperties::GetPropertyIndex (const ConstString &name) const
{
    return m_name_to_index.Find (name.GetCString(), SIZE_MAX);
}

const Property *
OptionValueProperties::GetProperty (const ExecutionContext *exe_ctx, bool will_modify, const ConstString &name) const
{
    return GetPropertyAtIndex (exe_ctx, will_modify, m_name_to_index.Find (name.GetCString(), SIZE_MAX));
}

const Property *
OptionValueProperties::GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
{
    return ProtectedGetPropertyAtIndex (idx);
}

lldb::OptionValueSP
OptionValueProperties::GetPropertyValueAtIndex (const ExecutionContext *exe_ctx,
                                                bool will_modify,
                                                uint32_t idx) const
{
    const Property *setting = GetPropertyAtIndex (exe_ctx, will_modify, idx);
    if (setting)
        return setting->GetValue();
    return OptionValueSP();
}

OptionValuePathMappings *
OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
{
    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
    if (value_sp)
        return value_sp->GetAsPathMappings();
    return nullptr;
}

OptionValueFileSpecList *
OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
{
    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
    if (value_sp)
        return value_sp->GetAsFileSpecList();
    return nullptr;
}

OptionValueArch *
OptionValueProperties::GetPropertyAtIndexAsOptionValueArch (const ExecutionContext *exe_ctx, uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
        return property->GetValue()->GetAsArch();
    return nullptr;
}

OptionValueLanguage *
OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage (const ExecutionContext *exe_ctx, uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
        return property->GetValue()->GetAsLanguage();
    return nullptr;
}

bool
OptionValueProperties::GetPropertyAtIndexAsArgs (const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
        {
            const OptionValueArray *array = value->GetAsArray();
            if (array)
                return array->GetArgs(args);
            else
            {
                const OptionValueDictionary *dict = value->GetAsDictionary();
                if (dict)
                    return dict->GetArgs(args);
            }
        }
    }
    return false;
}

bool
OptionValueProperties::SetPropertyAtIndexFromArgs (const ExecutionContext *exe_ctx, uint32_t idx, const Args &args)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
        {
            OptionValueArray *array = value->GetAsArray();
            if (array)
                return array->SetArgs(args, eVarSetOperationAssign).Success();
            else
            {
                OptionValueDictionary *dict = value->GetAsDictionary();
                if (dict)
                    return dict->SetArgs(args, eVarSetOperationAssign).Success();
            }
        }
    }
    return false;
}

bool
OptionValueProperties::GetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetBooleanValue(fail_value);
    }
    return fail_value;
}

bool
OptionValueProperties::SetPropertyAtIndexAsBoolean (const ExecutionContext *exe_ctx, uint32_t idx, bool new_value)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
        {
            value->SetBooleanValue(new_value);
            return true;
        }
    }
    return false;
}

OptionValueDictionary *
OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary (const ExecutionContext *exe_ctx, uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
        return property->GetValue()->GetAsDictionary();
    return nullptr;
}

int64_t
OptionValueProperties::GetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetEnumerationValue(fail_value);
    }
    return fail_value;
}

bool
OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->SetEnumerationValue(new_value);
    }
    return false;
}

const FormatEntity::Entry *
OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetFormatEntity();
    }
    return nullptr;
}

OptionValueFileSpec *
OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetAsFileSpec();
    }
    return nullptr;
}


FileSpec
OptionValueProperties::GetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetFileSpecValue();
    }
    return FileSpec();
}


bool
OptionValueProperties::SetPropertyAtIndexAsFileSpec (const ExecutionContext *exe_ctx, uint32_t idx, const FileSpec &new_file_spec)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->SetFileSpecValue(new_file_spec);
    }
    return false;
}

const RegularExpression *
OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex (const ExecutionContext *exe_ctx, uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetRegexValue();
    }
    return nullptr;
}

OptionValueSInt64 *
OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64 (const ExecutionContext *exe_ctx, uint32_t idx) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetAsSInt64();
    }
    return nullptr;
}

int64_t
OptionValueProperties::GetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetSInt64Value(fail_value);
    }
    return fail_value;
}

bool
OptionValueProperties::SetPropertyAtIndexAsSInt64 (const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->SetSInt64Value(new_value);
    }
    return false;
}

const char *
OptionValueProperties::GetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *fail_value) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetStringValue(fail_value);
    }
    return fail_value;
}

bool
OptionValueProperties::SetPropertyAtIndexAsString (const ExecutionContext *exe_ctx, uint32_t idx, const char *new_value)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->SetStringValue(new_value);
    }
    return false;
}

OptionValueString *
OptionValueProperties::GetPropertyAtIndexAsOptionValueString (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const
{
    OptionValueSP value_sp(GetPropertyValueAtIndex (exe_ctx, will_modify, idx));
    if (value_sp)
        return value_sp->GetAsString();
    return nullptr;
}


uint64_t
OptionValueProperties::GetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const
{
    const Property *property = GetPropertyAtIndex (exe_ctx, false, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->GetUInt64Value(fail_value);
    }
    return fail_value;
}

bool
OptionValueProperties::SetPropertyAtIndexAsUInt64 (const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value)
{
    const Property *property = GetPropertyAtIndex (exe_ctx, true, idx);
    if (property)
    {
        OptionValue *value = property->GetValue().get();
        if (value)
            return value->SetUInt64Value(new_value);
    }
    return false;
}

bool
OptionValueProperties::Clear ()
{
    const size_t num_properties = m_properties.size();
    for (size_t i=0; i<num_properties; ++i)
        m_properties[i].GetValue()->Clear();
    return true;
}


Error
OptionValueProperties::SetValueFromString (llvm::StringRef value, VarSetOperationType op)
{
    Error error;
    
//    Args args(value_cstr);
//    const size_t argc = args.GetArgumentCount();
    switch (op)
    {
        case eVarSetOperationClear:
            Clear ();
            break;
            
        case eVarSetOperationReplace:
        case eVarSetOperationAssign:
        case eVarSetOperationRemove:
        case eVarSetOperationInsertBefore:
        case eVarSetOperationInsertAfter:
        case eVarSetOperationAppend:
        case eVarSetOperationInvalid:
            error = OptionValue::SetValueFromString (value, op);
            break;
    }
    
    return error;
}

void
OptionValueProperties::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
{
    const size_t num_properties = m_properties.size();
    for (size_t i=0; i<num_properties; ++i)
    {
        const Property *property = GetPropertyAtIndex(exe_ctx, false, i);
        if (property)
        {
            OptionValue *option_value = property->GetValue().get();
            assert (option_value);
            const bool transparent_value = option_value->ValueIsTransparent ();
            property->Dump (exe_ctx,
                            strm,
                            dump_mask);
            if (!transparent_value)
                strm.EOL();
        }
    }
}

Error
OptionValueProperties::DumpPropertyValue (const ExecutionContext *exe_ctx,
                                          Stream &strm,
                                          const char *property_path,
                                          uint32_t dump_mask)
{
    Error error;
    const bool will_modify = false;
    lldb::OptionValueSP value_sp (GetSubValue (exe_ctx, property_path, will_modify, error));
    if (value_sp)
    {
        if (!value_sp->ValueIsTransparent ())
        {
            if (dump_mask & eDumpOptionName)
                strm.PutCString (property_path);
            if (dump_mask & ~eDumpOptionName)
                strm.PutChar (' ');
        }
        value_sp->DumpValue (exe_ctx, strm, dump_mask);
    }
    return error;
}

lldb::OptionValueSP
OptionValueProperties::DeepCopy () const
{
    assert(!"this shouldn't happen");
    return lldb::OptionValueSP();
}

const Property *
OptionValueProperties::GetPropertyAtPath (const ExecutionContext *exe_ctx,
                                          bool will_modify,
                                          const char *name) const
{
    const Property *property = nullptr;
    if (name && name[0])
    {
        const char *sub_name = nullptr;
        ConstString key;
        size_t key_len = ::strcspn (name, ".[{");
        
        if (name[key_len])
        {
            key.SetCStringWithLength (name, key_len);
            sub_name = name + key_len;
        }
        else
            key.SetCString (name);
        
        property = GetProperty (exe_ctx, will_modify, key);
        if (sub_name && property)
        {
            if (sub_name[0] == '.')
            {
                OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties();
                if (sub_properties)
                    return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, sub_name + 1);
            }
            property = nullptr;
        }
    }
    return property;
}

void
OptionValueProperties::DumpAllDescriptions (CommandInterpreter &interpreter,
                                            Stream &strm) const
{
    size_t max_name_len = 0;
    const size_t num_properties = m_properties.size();
    for (size_t i=0; i<num_properties; ++i)
    {
        const Property *property = ProtectedGetPropertyAtIndex(i);
        if (property)
            max_name_len = std::max<size_t>(property->GetName().GetLength(), max_name_len);
    }
    for (size_t i=0; i<num_properties; ++i)
    {
        const Property *property = ProtectedGetPropertyAtIndex(i);
        if (property)
            property->DumpDescription (interpreter, strm, max_name_len, false);
    }
}

void
OptionValueProperties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
{
    const size_t num_properties = m_properties.size();
    StreamString strm;
    for (size_t i=0; i<num_properties; ++i)
    {
        const Property *property = ProtectedGetPropertyAtIndex(i);
        if (property)
        {
            const OptionValueProperties *properties = property->GetValue()->GetAsProperties();
            if (properties)
            {
                properties->Apropos (keyword, matching_properties);
            }
            else
            {
                bool match = false;
                const char *name = property->GetName().GetCString();
                if (name && ::strcasestr(name, keyword))
                    match = true;
                else
                {
                    const char *desc = property->GetDescription();
                    if (desc && ::strcasestr(desc, keyword))
                        match = true;
                }
                if (match)
                {
                    matching_properties.push_back (property);
                }
            }
        }
    }
}

lldb::OptionValuePropertiesSP
OptionValueProperties::GetSubProperty (const ExecutionContext *exe_ctx,
                                       const ConstString &name)
{
    lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false));
    if (option_value_sp)
    {
        OptionValueProperties *ov_properties = option_value_sp->GetAsProperties ();
        if (ov_properties)
            return ov_properties->shared_from_this();
    }
    return lldb::OptionValuePropertiesSP();
}



