//===-- CommandObjectApropos.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 "CommandObjectApropos.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Property.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/Support/Regex.h"

using namespace lldb;
using namespace lldb_private;

// CommandObjectApropos

CommandObjectApropos::CommandObjectApropos(CommandInterpreter &interpreter)
    : CommandObjectParsed(
          interpreter, "apropos",
          "List debugger commands related to a word or subject.", nullptr) {
  AddSimpleArgumentList(eArgTypeSearchWord);
}

CommandObjectApropos::~CommandObjectApropos() = default;

void CommandObjectApropos::DoExecute(Args &args, CommandReturnObject &result) {
  const size_t argc = args.GetArgumentCount();

  if (argc == 1) {
    auto search_word = args[0].ref();
    if (!search_word.empty()) {
      ReturnStatus return_status = eReturnStatusSuccessFinishNoResult;

      std::string escaped_search_word;
      std::optional<Stream::HighlightSettings> highlight;
      Debugger &dbg = GetDebugger();
      if (dbg.GetUseColor()) {
        escaped_search_word = llvm::Regex::escape(search_word);
        highlight.emplace(escaped_search_word, dbg.GetRegexMatchAnsiPrefix(),
                          dbg.GetRegexMatchAnsiSuffix(), true);
      }

      // Find all commands matching the search word.
      StringList commands_found;
      StringList commands_help;
      m_interpreter.FindCommandsForApropos(
          search_word, commands_found, commands_help, true, true, true, true);

      if (commands_found.GetSize() == 0) {
        result.AppendMessageWithFormatv(
            "No commands found pertaining to '{0}'. "
            "Try 'help' to see a complete list of "
            "debugger commands.",
            args[0].c_str());
      } else {
        result.AppendMessageWithFormatv(
            "The following commands may relate to '{0}':", args[0].c_str());
        const size_t commands_max_len = commands_found.GetMaxStringLength();
        for (size_t i = 0; i < commands_found.GetSize(); ++i)
          m_interpreter.OutputFormattedHelpText(
              result.GetOutputStream(), commands_found.GetStringAtIndex(i),
              "--", commands_help.GetStringAtIndex(i), commands_max_len,
              highlight);
        return_status = eReturnStatusSuccessFinishResult;
      }

      // Find all the properties matching the search word.
      size_t properties_max_len = 0;
      std::vector<const Property *> properties;
      const size_t num_properties =
          GetDebugger().Apropos(search_word, properties);
      for (const Property *prop : properties) {
        StreamString qualified_name;
        prop->DumpQualifiedName(qualified_name);
        properties_max_len =
            std::max(properties_max_len, qualified_name.GetString().size());
      }

      if (num_properties == 0) {
        result.AppendMessageWithFormatv(
            "No settings found pertaining to '{0}'. "
            "Try 'settings show' to see a complete list of "
            "debugger settings.",
            args[0].c_str());

      } else {
        result.AppendMessageWithFormatv(
            "\nThe following settings variables may relate to '{0}': \n\n",
            search_word);

        const bool dump_qualified_name = true;
        for (size_t i = 0; i < num_properties; ++i)
          properties[i]->DumpDescription(
              m_interpreter, result.GetOutputStream(), properties_max_len,
              dump_qualified_name, highlight);
        return_status = eReturnStatusSuccessFinishResult;
      }

      result.SetStatus(return_status);
    } else {
      result.AppendError("'' is not a valid search word.\n");
    }
  } else {
    result.AppendError("'apropos' must be called with exactly one argument.\n");
  }
}
