//===-- CommandObjectRegexCommand.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 "CommandObjectRegexCommand.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"

#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"

using namespace lldb;
using namespace lldb_private;

// CommandObjectRegexCommand constructor
CommandObjectRegexCommand::CommandObjectRegexCommand(
    CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help,
    llvm::StringRef syntax, uint32_t completion_type_mask, bool is_removable)
    : CommandObjectRaw(interpreter, name, help, syntax),
      m_completion_type_mask(completion_type_mask),
      m_is_removable(is_removable) {}

// Destructor
CommandObjectRegexCommand::~CommandObjectRegexCommand() = default;

llvm::Expected<std::string> CommandObjectRegexCommand::SubstituteVariables(
    llvm::StringRef input,
    const llvm::SmallVectorImpl<llvm::StringRef> &replacements) {
  std::string buffer;
  llvm::raw_string_ostream output(buffer);

  llvm::SmallVector<llvm::StringRef, 4> parts;
  input.split(parts, '%');

  output << parts[0];
  for (llvm::StringRef part : drop_begin(parts)) {
    size_t idx = 0;
    if (part.consumeInteger(10, idx))
      output << '%';
    else if (idx < replacements.size())
      output << replacements[idx];
    else
      return llvm::make_error<llvm::StringError>(
          llvm::formatv("%{0} is out of range: not enough arguments specified",
                        idx),
          llvm::errc::invalid_argument);
    output << part;
  }

  return buffer;
}

void CommandObjectRegexCommand::DoExecute(llvm::StringRef command,
                                          CommandReturnObject &result) {
  EntryCollection::const_iterator pos, end = m_entries.end();
  for (pos = m_entries.begin(); pos != end; ++pos) {
    llvm::SmallVector<llvm::StringRef, 4> matches;
    if (pos->regex.Execute(command, &matches)) {
      llvm::Expected<std::string> new_command =
          SubstituteVariables(pos->command, matches);
      if (!new_command) {
        result.SetError(new_command.takeError());
        return;
      }

      // Interpret the new command and return this as the result!
      if (m_interpreter.GetExpandRegexAliases())
        result.GetOutputStream().Printf("%s\n", new_command->c_str());
      // We don't have to pass an override_context here, as the command that 
      // called us should have set up the context appropriately.
      bool force_repeat_command = true;
      m_interpreter.HandleCommand(new_command->c_str(), eLazyBoolNo, result,
                                  force_repeat_command);
      return;
    }
  }
  result.SetStatus(eReturnStatusFailed);
  if (!GetSyntax().empty())
    result.AppendError(GetSyntax());
  else
    result.GetErrorStream() << "Command contents '" << command
                            << "' failed to match any "
                               "regular expression in the '"
                            << m_cmd_name << "' regex ";
}

bool CommandObjectRegexCommand::AddRegexCommand(llvm::StringRef re_cstr,
                                                llvm::StringRef command_cstr) {
  m_entries.resize(m_entries.size() + 1);
  // Only add the regular expression if it compiles
  m_entries.back().regex = RegularExpression(re_cstr);
  if (m_entries.back().regex.IsValid()) {
    m_entries.back().command = command_cstr.str();
    return true;
  }
  // The regex didn't compile...
  m_entries.pop_back();
  return false;
}

void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) {
  if (m_completion_type_mask) {
    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
  }
}
