//===-- 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"

using namespace lldb;
using namespace lldb_private;

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

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

bool 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)) {
      std::string new_command(pos->command);
      char percent_var[8];
      size_t idx, percent_var_idx;
      for (uint32_t match_idx = 1; match_idx <= m_max_matches; ++match_idx) {
        if (match_idx < matches.size()) {
          const std::string match_str = matches[match_idx].str();
          const int percent_var_len =
              ::snprintf(percent_var, sizeof(percent_var), "%%%u", match_idx);
          for (idx = 0; (percent_var_idx = new_command.find(
                             percent_var, idx)) != std::string::npos;) {
            new_command.erase(percent_var_idx, percent_var_len);
            new_command.insert(percent_var_idx, match_str);
            idx = percent_var_idx + match_str.size();
          }
        }
      }
      // Interpret the new command and return this as the result!
      if (m_interpreter.GetExpandRegexAliases())
        result.GetOutputStream().Printf("%s\n", new_command.c_str());
      // Pass in true for "no context switching".  The command that called us
      // should have set up the context appropriately, we shouldn't have to
      // redo that.
      return m_interpreter.HandleCommand(new_command.c_str(),
                                         eLazyBoolCalculate, result);
    }
  }
  result.SetStatus(eReturnStatusFailed);
  if (!GetSyntax().empty())
    result.AppendError(GetSyntax());
  else
    result.GetOutputStream() << "Command contents '" << command
                             << "' failed to match any "
                                "regular expression in the '"
                             << m_cmd_name << "' regex ";
  return false;
}

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) {
    CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), m_completion_type_mask, request, nullptr);
  }
}
