//===-- CommandObjectStats.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 "CommandObjectStats.h"
#include "lldb/Core/Debugger.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"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

class CommandObjectStatsEnable : public CommandObjectParsed {
public:
  CommandObjectStatsEnable(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "enable",
                            "Enable statistics collection", nullptr,
                            eCommandProcessMustBePaused) {}

  ~CommandObjectStatsEnable() override = default;

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    if (DebuggerStats::GetCollectingStats()) {
      result.AppendError("statistics already enabled");
      return;
    }

    DebuggerStats::SetCollectingStats(true);
    result.SetStatus(eReturnStatusSuccessFinishResult);
  }
};

class CommandObjectStatsDisable : public CommandObjectParsed {
public:
  CommandObjectStatsDisable(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "disable",
                            "Disable statistics collection", nullptr,
                            eCommandProcessMustBePaused) {}

  ~CommandObjectStatsDisable() override = default;

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    if (!DebuggerStats::GetCollectingStats()) {
      result.AppendError("need to enable statistics before disabling them");
      return;
    }

    DebuggerStats::SetCollectingStats(false);
    result.SetStatus(eReturnStatusSuccessFinishResult);
  }
};

#define LLDB_OPTIONS_statistics_dump
#include "CommandOptions.inc"

class CommandObjectStatsDump : public CommandObjectParsed {
  class CommandOptions : public Options {
  public:
    CommandOptions() { OptionParsingStarting(nullptr); }

    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 'a':
        m_all_targets = true;
        break;
      case 's':
        m_stats_options.SetSummaryOnly(true);
        break;
      case 'f':
        m_stats_options.SetLoadAllDebugInfo(true);
        break;
      case 'r':
        if (llvm::Expected<bool> bool_or_error =
                OptionArgParser::ToBoolean("--targets", option_arg))
          m_stats_options.SetIncludeTargets(*bool_or_error);
        else
          error = Status::FromError(bool_or_error.takeError());
        break;
      case 'm':
        if (llvm::Expected<bool> bool_or_error =
                OptionArgParser::ToBoolean("--modules", option_arg))
          m_stats_options.SetIncludeModules(*bool_or_error);
        else
          error = Status::FromError(bool_or_error.takeError());
        break;
      case 't':
        if (llvm::Expected<bool> bool_or_error =
                OptionArgParser::ToBoolean("--transcript", option_arg))
          m_stats_options.SetIncludeTranscript(*bool_or_error);
        else
          error = Status::FromError(bool_or_error.takeError());
        break;
      case 'p':
        if (llvm::Expected<bool> bool_or_error =
                OptionArgParser::ToBoolean("--plugins", option_arg))
          m_stats_options.SetIncludePlugins(*bool_or_error);
        else
          error = Status::FromError(bool_or_error.takeError());
        break;
      default:
        llvm_unreachable("Unimplemented option");
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      m_all_targets = false;
      m_stats_options = StatisticsOptions();
    }

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

    const StatisticsOptions &GetStatisticsOptions() { return m_stats_options; }

    bool m_all_targets = false;
    StatisticsOptions m_stats_options = StatisticsOptions();
  };

public:
  CommandObjectStatsDump(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "statistics dump", "Dump metrics in JSON format",
            "statistics dump [<options>]", eCommandRequiresTarget) {}

  ~CommandObjectStatsDump() override = default;

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

protected:
  void DoExecute(Args &command, CommandReturnObject &result) override {
    Target *target = nullptr;
    if (!m_options.m_all_targets)
      target = m_exe_ctx.GetTargetPtr();

    // Check if transcript is requested but transcript saving is disabled
    const StatisticsOptions &stats_options = m_options.GetStatisticsOptions();
    if (stats_options.GetIncludeTranscript() &&
        !GetDebugger().GetCommandInterpreter().GetSaveTranscript()) {
      result.AppendWarning(
          "transcript requested but none was saved. Enable with "
          "'settings set interpreter.save-transcript true'");
    }

    result.AppendMessageWithFormatv(
        "{0:2}",
        DebuggerStats::ReportStatistics(GetDebugger(), target, stats_options));
    result.SetStatus(eReturnStatusSuccessFinishResult);
  }

  CommandOptions m_options;
};

CommandObjectStats::CommandObjectStats(CommandInterpreter &interpreter)
    : CommandObjectMultiword(interpreter, "statistics",
                             "Print statistics about a debugging session",
                             "statistics <subcommand> [<subcommand-options>]") {
  LoadSubCommand("enable",
                 CommandObjectSP(new CommandObjectStatsEnable(interpreter)));
  LoadSubCommand("disable",
                 CommandObjectSP(new CommandObjectStatsDisable(interpreter)));
  LoadSubCommand("dump",
                 CommandObjectSP(new CommandObjectStatsDump(interpreter)));
}

CommandObjectStats::~CommandObjectStats() = default;
