//===-- OptionValueString.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/OptionValueString.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
OptionValueString::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
{
    if (dump_mask & eDumpOptionType)
        strm.Printf ("(%s)", GetTypeAsCString ());
    if (dump_mask & eDumpOptionValue)
    {
        if (dump_mask & eDumpOptionType)
            strm.PutCString (" = ");
        if (!m_current_value.empty() || m_value_was_set)
        {
            if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
            {
                std::string expanded_escape_value;
                Args::ExpandEscapedCharacters(m_current_value.c_str(), expanded_escape_value);
                if (dump_mask & eDumpOptionRaw)
                    strm.Printf ("%s", expanded_escape_value.c_str());
                else
                    strm.Printf ("\"%s\"", expanded_escape_value.c_str());                
            }
            else
            {
                if (dump_mask & eDumpOptionRaw)
                    strm.Printf ("%s", m_current_value.c_str());
                else
                    strm.Printf ("\"%s\"", m_current_value.c_str());
            }
        }
    }
}

Error
OptionValueString::SetValueFromString (llvm::StringRef value,
                                        VarSetOperationType op)
{
    Error error;

    std::string value_str = value.str();
    value = value.trim();
    if (value.size() > 0)
    {
        switch (value.front())
        {
        case '"':
        case '\'':
            {
                if (value.size() <= 1 || value.back() != value.front())
                {
                    error.SetErrorString("mismatched quotes");
                    return error;
                }
                value = value.drop_front().drop_back();
            }
            break;
        }
        value_str = value.str();
    }

    switch (op)
    {
    case eVarSetOperationInvalid:
    case eVarSetOperationInsertBefore:
    case eVarSetOperationInsertAfter:
    case eVarSetOperationRemove:
        if (m_validator)
        {
            error = m_validator(value_str.c_str(),m_validator_baton);
            if (error.Fail())
                return error;
        }
        error = OptionValue::SetValueFromString (value, op);
        break;

    case eVarSetOperationAppend:
        {
            std::string new_value(m_current_value);
            if (value.size() > 0)
            {
                if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
                {
                    std::string str;
                    Args::EncodeEscapeSequences (value_str.c_str(), str);
                    new_value.append(str);
                }
                else
                    new_value.append(value);
            }
            if (m_validator)
            {
                error = m_validator(new_value.c_str(),m_validator_baton);
                if (error.Fail())
                    return error;
            }
            m_current_value.assign(new_value);
            NotifyValueChanged();
        }
        break;

    case eVarSetOperationClear:
        Clear ();
        NotifyValueChanged();
        break;

    case eVarSetOperationReplace:
    case eVarSetOperationAssign:
        if (m_validator)
        {
            error = m_validator(value_str.c_str(), m_validator_baton);
            if (error.Fail())
                return error;
        }
        m_value_was_set = true;
        if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
        {
            Args::EncodeEscapeSequences (value_str.c_str(), m_current_value);
        }
        else
        {
            SetCurrentValue (value_str.c_str());
        }
        NotifyValueChanged();
        break;
    }
    return error;
}


lldb::OptionValueSP
OptionValueString::DeepCopy () const
{
    return OptionValueSP(new OptionValueString(*this));
}

Error
OptionValueString::SetCurrentValue (const char *value)
{
    if (m_validator)
    {
        Error error(m_validator(value,m_validator_baton));
        if (error.Fail())
            return error;
    }
    if (value && value[0])
        m_current_value.assign (value);
    else
        m_current_value.clear();
    return Error();
}

Error
OptionValueString::AppendToCurrentValue (const char *value)
{
    if (value && value[0])
    {
        if (m_validator)
        {
            std::string new_value(m_current_value);
            new_value.append(value);
            Error error(m_validator(value,m_validator_baton));
            if (error.Fail())
                return error;
            m_current_value.assign(new_value);
        }
        else
            m_current_value.append (value);
    }
    return Error();
}
