//===-- 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();
}
