//===-- CommandObjectPlugin.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 "CommandObjectPlugin.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandOptionArgumentTable.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"

using namespace lldb;
using namespace lldb_private;

class CommandObjectPluginLoad : public CommandObjectParsed {
public:
  CommandObjectPluginLoad(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "plugin load",
                            "Import a dylib that implements an LLDB plugin.",
                            nullptr) {
    AddSimpleArgumentList(eArgTypeFilename);
  }

  ~CommandObjectPluginLoad() override = default;

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    size_t argc = command.GetArgumentCount();

    if (argc != 1) {
      result.AppendError("'plugin load' requires one argument");
      return;
    }

    Status error;

    FileSpec dylib_fspec(command[0].ref());
    FileSystem::Instance().Resolve(dylib_fspec);

    if (GetDebugger().LoadPlugin(dylib_fspec, error))
      result.SetStatus(eReturnStatusSuccessFinishResult);
    else {
      result.AppendError(error.AsCString());
    }
  }
};

namespace {
// Helper function to perform an action on each matching plugin.
// The action callback is given the containing namespace along with plugin info
// for each matching plugin.
static int ActOnMatchingPlugins(
    const llvm::StringRef pattern,
    std::function<void(const PluginNamespace &plugin_namespace,
                       const std::vector<RegisteredPluginInfo> &plugin_info)>
        action) {
  int num_matching = 0;

  for (const PluginNamespace &plugin_namespace :
       PluginManager::GetPluginNamespaces()) {

    std::vector<RegisteredPluginInfo> matching_plugins;
    for (const RegisteredPluginInfo &plugin_info :
         plugin_namespace.get_info()) {
      if (PluginManager::MatchPluginName(pattern, plugin_namespace,
                                         plugin_info))
        matching_plugins.push_back(plugin_info);
    }

    if (!matching_plugins.empty()) {
      num_matching += matching_plugins.size();
      action(plugin_namespace, matching_plugins);
    }
  }

  return num_matching;
}

// Call the "SetEnable" function for each matching plugins.
// Used to share the majority of the code between the enable
// and disable commands.
int SetEnableOnMatchingPlugins(const llvm::StringRef &pattern,
                               CommandReturnObject &result, bool enabled,
                               Debugger &requesting_debugger,
                               PluginDomainKind domain) {
  return ActOnMatchingPlugins(
      pattern, [&](const PluginNamespace &plugin_namespace,
                   const std::vector<RegisteredPluginInfo> &plugins) {
        auto PrintEnablement = [enabled,
                                &result](const RegisteredPluginInfo plugin) {
          result.AppendMessageWithFormatv("  {0} {1, -30} {2}",
                                          enabled ? "[+]" : "[-]", plugin.name,
                                          plugin.description);
        };

        result.AppendMessage(plugin_namespace.name);
        for (const auto &plugin : plugins) {
          if (plugin_namespace.SupportsOnlyDomain(
                  PluginDomainKind::ePluginDomainKindGlobal)) {
            bool success = true;
            if (domain != ePluginDomainKindGlobal) {
              result.AppendErrorWithFormatv(
                  "failed to {} plugin {}.{}: {} domain is not supported",
                  enabled ? "enable" : "disable", plugin_namespace.name,
                  plugin.name, PluginManager::PluginDomainKindToStr(domain));
              continue;
            }
            success = (*plugin_namespace.GetSetEnabledGlobalFn())(plugin.name,
                                                                  enabled);

            if (!success) {
              result.AppendErrorWithFormatv("failed to {} plugin {}.{}",
                                            enabled ? "enable" : "disable",
                                            plugin_namespace.name, plugin.name);
              continue;
            }
            PrintEnablement(plugin);
            continue;
          }

          // Handle plugin namespace that supports more than just the global
          // domain. Currently this is just the instrumentation-runtime
          // namespace.
          if (!plugin_namespace.SupportsDomain(domain)) {
            result.AppendErrorWithFormatv(
                "failed to {0} plugin {1}.{2}: the {1} namespace "
                "does not support the {3} domain",
                enabled ? "enable" : "disable", plugin_namespace.name,
                plugin.name, PluginManager::PluginDomainKindToStr(domain));
            continue;
          }
          assert(plugin_namespace.GetSetEnabledAllDomainsFn().has_value());
          llvm::Error error = (*plugin_namespace.GetSetEnabledAllDomainsFn())(
              plugin.name, enabled, requesting_debugger, domain);

          if (error) {
            result.AppendErrorWithFormatv("failed to {} plugin {}.{}: {}",
                                          enabled ? "enable" : "disable",
                                          plugin_namespace.name, plugin.name,
                                          llvm::toString(std::move(error)));
            continue;
          }
          PrintEnablement(plugin);
        }
      });
}

static std::string ConvertJSONToPrettyString(const llvm::json::Value &json) {
  std::string str;
  llvm::raw_string_ostream os(str);
  os << llvm::formatv("{0:2}", json).str();
  os.flush();
  return str;
}

#define LLDB_OPTIONS_plugin_list
#include "CommandOptions.inc"

// These option definitions are used by the plugin list command.
class PluginListCommandOptions : public Options {
  static constexpr const PluginDomainKind kDefaultDomain =
      ePluginDomainKindGlobal;

public:
  PluginListCommandOptions() = default;

  ~PluginListCommandOptions() override = default;

  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                        ExecutionContext *execution_context) override {
    Status error;
    const int short_option = m_getopt_table[option_idx].val;

    switch (short_option) {
    case 'j':
      m_json_format = true;
      break;
    case 'd':
      m_domain = static_cast<PluginDomainKind>(OptionArgParser::ToOptionEnum(
          option_arg, GetDefinitions()[option_idx].enum_values, kDefaultDomain,
          error));
      break;
    default:
      llvm_unreachable("Unimplemented option");
    }

    return error;
  }

  void OptionParsingStarting(ExecutionContext *execution_context) override {
    m_json_format = false;
    m_domain = kDefaultDomain;
  }

  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
    return llvm::ArrayRef(g_plugin_list_options);
  }

  // Instance variables to hold the values for command options.
  bool m_json_format = false;
  PluginDomainKind m_domain = kDefaultDomain;
};
} // namespace

class CommandObjectPluginList : public CommandObjectParsed {
public:
  CommandObjectPluginList(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "plugin list",
                            "Report info about registered LLDB plugins.",
                            nullptr) {
    AddSimpleArgumentList(eArgTypeManagedPlugin);
    SetHelpLong(R"(
Display information about registered plugins.
The plugin information is formatted as shown below:

    <plugin-namespace>
      [+] <plugin-name>                  Plugin #1 description
      [-] <plugin-name>                  Plugin #2 description

An enabled plugin is marked with [+] and a disabled plugin is marked with [-].

Plugins can be listed by namespace and name with:

  plugin list <plugin-namespace>[.<plugin-name>]

Plugins can be listed by namespace alone or with a fully qualified name. When listed
with just a namespace all plugins in that namespace are listed.  When no arguments
are given all plugins are listed.

Examples:
List all plugins

  (lldb) plugin list

List all plugins in the system-runtime namespace

  (lldb) plugin list system-runtime

List only the plugin 'foo' matching a fully qualified name exactly

  (lldb) plugin list system-runtime.foo
)");
  }

  ~CommandObjectPluginList() override = default;

  Options *GetOptions() override { return &m_options; }

  void
  HandleArgumentCompletion(CompletionRequest &request,
                           OptionElementVector &opt_element_vector) override {
    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), lldb::eManagedPluginCompletion, request,
        nullptr);
  }

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    size_t argc = command.GetArgumentCount();
    result.SetStatus(eReturnStatusSuccessFinishResult);

    // Create a temporary vector to hold the patterns to simplify the logic
    // for the case when the user passes no patterns
    std::vector<llvm::StringRef> patterns;
    patterns.reserve(argc == 0 ? 1 : argc);
    if (argc == 0)
      patterns.push_back("");
    else
      for (size_t i = 0; i < argc; ++i)
        patterns.push_back(command[i].ref());

    if (m_options.m_json_format)
      OutputJsonFormat(patterns, result, GetDebugger(), m_options.m_domain);
    else
      OutputTextFormat(patterns, result, GetDebugger(), m_options.m_domain);
  }

private:
  void OutputJsonFormat(const std::vector<llvm::StringRef> &patterns,
                        CommandReturnObject &result,
                        Debugger &requesting_debugger,
                        PluginDomainKind domain) {
    if (domain != PluginDomainKind::ePluginDomainKindGlobal) {
      result.AppendErrorWithFormatv(
          "{} domain is not supported",
          PluginManager::PluginDomainKindToStr(domain));
      return;
    }

    llvm::json::Object obj;
    bool found_empty = false;
    for (const llvm::StringRef pattern : patterns) {
      llvm::json::Object pat_obj = PluginManager::GetJSON(pattern);
      if (pat_obj.empty()) {
        found_empty = true;
        result.AppendErrorWithFormat(
            "Found no matching plugins for pattern '%s'", pattern.data());
        break;
      }
      for (auto &entry : pat_obj) {
        obj[entry.first] = std::move(entry.second);
      }
    }
    if (!found_empty) {
      result.AppendMessage(ConvertJSONToPrettyString(std::move(obj)));
    }
  }

  void OutputTextFormat(const std::vector<llvm::StringRef> &patterns,
                        CommandReturnObject &result,
                        Debugger &requesting_debugger,
                        PluginDomainKind domain) {
    if (domain != PluginDomainKind::ePluginDomainKindGlobal) {
      result.AppendErrorWithFormatv(
          "{} domain is not supported",
          PluginManager::PluginDomainKindToStr(domain));
      return;
    }

    for (const llvm::StringRef pattern : patterns) {
      int num_matching = ActOnMatchingPlugins(
          pattern, [&](const PluginNamespace &plugin_namespace,
                       const std::vector<RegisteredPluginInfo> &plugins) {
            result.AppendMessage(plugin_namespace.name);
            for (auto &plugin : plugins) {
              result.AppendMessageWithFormatv("  {0} {1, -30} {2}",
                                              plugin.enabled ? "[+]" : "[-]",
                                              plugin.name, plugin.description);
            }
          });
      if (num_matching == 0) {
        result.AppendErrorWithFormat(
            "Found no matching plugins for pattern '%s'", pattern.data());
        break;
      }
    }
  }

  PluginListCommandOptions m_options;
};

static void DoPluginEnableDisable(Args &command, CommandReturnObject &result,
                                  bool enable, Debugger &requesting_debugger,
                                  PluginDomainKind domain) {
  const char *name = enable ? "enable" : "disable";
  size_t argc = command.GetArgumentCount();
  if (argc == 0) {
    result.AppendErrorWithFormat("'plugin %s' requires one or more arguments",
                                 name);
    return;
  }
  result.SetStatus(eReturnStatusSuccessFinishResult);

  for (size_t i = 0; i < argc; ++i) {
    llvm::StringRef pattern = command[i].ref();
    int num_matching = SetEnableOnMatchingPlugins(pattern, result, enable,
                                                  requesting_debugger, domain);

    if (num_matching == 0) {
      result.AppendErrorWithFormat(
          "Found no matching plugins to %s for pattern '%s'", name,
          pattern.data());
      break;
    }
  }
}

#define LLDB_OPTIONS_plugin_enable
#include "CommandOptions.inc"

#define LLDB_OPTIONS_plugin_disable
#include "CommandOptions.inc"

// Options class for the --domain flag, shared by plugin enable and
// plugin disable (and reusable by plugin status in the future).
class PluginDomainOptions : public Options {
  static constexpr const PluginDomainKind kDefaultDomain =
      ePluginDomainKindGlobal;

public:
  PluginDomainOptions(llvm::ArrayRef<OptionDefinition> definitions)
      : m_definitions(definitions) {}

  Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
                        ExecutionContext *execution_context) override {
    Status error;
    const int short_option = m_getopt_table[option_idx].val;
    switch (short_option) {
    case 'd':
      m_domain = static_cast<PluginDomainKind>(OptionArgParser::ToOptionEnum(
          option_arg, GetDefinitions()[option_idx].enum_values, kDefaultDomain,
          error));
      break;
    default:
      llvm_unreachable("Unimplemented option");
    }
    return error;
  }

  void OptionParsingStarting(ExecutionContext *execution_context) override {
    m_domain = kDefaultDomain;
  }

  llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
    return m_definitions;
  }

  PluginDomainKind m_domain = kDefaultDomain;

private:
  llvm::ArrayRef<OptionDefinition> m_definitions;
};

class CommandObjectPluginEnable : public CommandObjectParsed {
public:
  CommandObjectPluginEnable(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "plugin enable",
                            "Enable registered LLDB plugins.", nullptr),
        m_options(llvm::ArrayRef(g_plugin_enable_options)) {
    AddSimpleArgumentList(eArgTypeManagedPlugin);
  }

  void
  HandleArgumentCompletion(CompletionRequest &request,
                           OptionElementVector &opt_element_vector) override {
    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), lldb::eManagedPluginCompletion, request,
        nullptr);
  }

  ~CommandObjectPluginEnable() override = default;

  Options *GetOptions() override { return &m_options; }

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    DoPluginEnableDisable(command, result, /*enable=*/true, GetDebugger(),
                          m_options.m_domain);
  }

  PluginDomainOptions m_options;
};

class CommandObjectPluginDisable : public CommandObjectParsed {
public:
  CommandObjectPluginDisable(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "plugin disable",
                            "Disable registered LLDB plugins.", nullptr),
        m_options(llvm::ArrayRef(g_plugin_disable_options)) {
    AddSimpleArgumentList(eArgTypeManagedPlugin);
  }

  void
  HandleArgumentCompletion(CompletionRequest &request,
                           OptionElementVector &opt_element_vector) override {
    lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
        GetCommandInterpreter(), lldb::eManagedPluginCompletion, request,
        nullptr);
  }

  ~CommandObjectPluginDisable() override = default;

  Options *GetOptions() override { return &m_options; }

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    DoPluginEnableDisable(command, result, /*enable=*/false, GetDebugger(),
                          m_options.m_domain);
  }

  PluginDomainOptions m_options;
};

CommandObjectPlugin::CommandObjectPlugin(CommandInterpreter &interpreter)
    : CommandObjectMultiword(interpreter, "plugin",
                             "Commands for managing LLDB plugins.",
                             "plugin <subcommand> [<subcommand-options>]") {
  LoadSubCommand("load",
                 CommandObjectSP(new CommandObjectPluginLoad(interpreter)));
  LoadSubCommand("list",
                 CommandObjectSP(new CommandObjectPluginList(interpreter)));
  LoadSubCommand("enable",
                 CommandObjectSP(new CommandObjectPluginEnable(interpreter)));
  LoadSubCommand("disable",
                 CommandObjectSP(new CommandObjectPluginDisable(interpreter)));
}

CommandObjectPlugin::~CommandObjectPlugin() = default;
