//===-- OptionValueFileColonLine.cpp---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Interpreter/OptionValueFileColonLine.h"

#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/State.h"

using namespace lldb;
using namespace lldb_private;

// This is an OptionValue for parsing file:line:column specifications.
// I set the completer to "source file" which isn't quite right, but we can
// only usefully complete in the file name part of it so it should be good
// enough.
OptionValueFileColonLine::OptionValueFileColonLine()
    : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER),
      m_column_number(LLDB_INVALID_COLUMN_NUMBER),
      m_completion_mask(CommandCompletions::eSourceFileCompletion) {}

OptionValueFileColonLine::OptionValueFileColonLine(llvm::StringRef input)
    : OptionValue(), m_file_spec(), m_line_number(LLDB_INVALID_LINE_NUMBER),
      m_column_number(LLDB_INVALID_COLUMN_NUMBER),
      m_completion_mask(CommandCompletions::eSourceFileCompletion) {
  SetValueFromString(input, eVarSetOperationAssign);
}

void OptionValueFileColonLine::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_file_spec)
      strm << '"' << m_file_spec.GetPath().c_str() << '"';
    if (m_line_number != LLDB_INVALID_LINE_NUMBER)
      strm.Printf(":%d", m_line_number);
    if (m_column_number != LLDB_INVALID_COLUMN_NUMBER)
      strm.Printf(":%d", m_column_number);
  }
}

Status OptionValueFileColonLine::SetValueFromString(llvm::StringRef value,
                                                    VarSetOperationType op) {
  Status error;
  switch (op) {
  case eVarSetOperationClear:
    Clear();
    NotifyValueChanged();
    break;

  case eVarSetOperationReplace:
  case eVarSetOperationAssign:
    if (value.size() > 0) {
      // This is in the form filename:linenumber:column.
      // I wish we could use filename:linenumber.column, that would make the
      // parsing unambiguous and so much easier...
      // But clang & gcc both print the output with two : so we're stuck with
      // the two colons.  Practically, the only actual ambiguity this introduces
      // is with files like "foo:10", which doesn't seem terribly likely.

      // Providing the column is optional, so the input value might have one or
      // two colons.  First pick off the last colon separated piece.
      // It has to be there, since the line number is required:
      llvm::StringRef last_piece;
      llvm::StringRef left_of_last_piece;

      std::tie(left_of_last_piece, last_piece) = value.rsplit(':');
      if (last_piece.empty()) {
        error.SetErrorStringWithFormat("Line specifier must include file and "
                                       "line: '%s'",
                                       value.str().c_str());
        return error;
      }

      // Now see if there's another colon and if so pull out the middle piece:
      // Then check whether the middle piece is an integer.  If it is, then it
      // was the line number, and if it isn't we're going to assume that there
      // was a colon in the filename (see note at the beginning of the function)
      // and ignore it.
      llvm::StringRef file_name;
      llvm::StringRef middle_piece;

      std::tie(file_name, middle_piece) = left_of_last_piece.rsplit(':');
      if (middle_piece.empty() || !llvm::to_integer(middle_piece, 
                                                    m_line_number)) {
        // The middle piece was empty or not an integer, so there were only two
        // legit pieces; our original division was right.  Reassign the file
        // name and pull out the line number:
        file_name = left_of_last_piece;
        if (!llvm::to_integer(last_piece, m_line_number)) {
          error.SetErrorStringWithFormat("Bad line number value '%s' in: '%s'",
                                         last_piece.str().c_str(),
                                         value.str().c_str());
          return error;
        }
      } else {
        // There were three pieces, and we've got the line number.  So now
        // we just need to check the column number which was the last peice.
        if (!llvm::to_integer(last_piece, m_column_number)) {
          error.SetErrorStringWithFormat("Bad column value '%s' in: '%s'",
                                         last_piece.str().c_str(),
                                         value.str().c_str());
          return error;
        }
      }

      m_value_was_set = true;
      m_file_spec.SetFile(file_name, FileSpec::Style::native);
      NotifyValueChanged();
    } else {
      error.SetErrorString("invalid value string");
    }
    break;

  case eVarSetOperationInsertBefore:
  case eVarSetOperationInsertAfter:
  case eVarSetOperationRemove:
  case eVarSetOperationAppend:
  case eVarSetOperationInvalid:
    error = OptionValue::SetValueFromString(value, op);
    break;
  }
  return error;
}

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

void OptionValueFileColonLine::AutoComplete(CommandInterpreter &interpreter,
                                            CompletionRequest &request) {
  CommandCompletions::InvokeCommonCompletionCallbacks(
      interpreter, m_completion_mask, request, nullptr);
}
