//===-- CommandObjectDiagnostics.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 "CommandObjectDiagnostics.h"
#include "lldb/Core/BugReporter.h"
#include "lldb/Core/Diagnostics.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Interpreter/CommandOptionArgumentTable.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionValueEnumeration.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Interpreter/Options.h"

#include "llvm/Support/JSON.h"

using namespace lldb;
using namespace lldb_private;

#define LLDB_OPTIONS_diagnostics_dump
#include "CommandOptions.inc"

#define LLDB_OPTIONS_diagnostics_report
#include "CommandOptions.inc"

class CommandObjectDiagnosticsDump : public CommandObjectParsed {
public:
  // Constructors and Destructors
  CommandObjectDiagnosticsDump(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "diagnostics dump",
                            "Dump diagnostics to disk", nullptr) {}

  ~CommandObjectDiagnosticsDump() override = default;

  class CommandOptions : public Options {
  public:
    CommandOptions() = default;

    ~CommandOptions() 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 'd':
        directory.SetDirectory(option_arg);
        break;
      default:
        llvm_unreachable("Unimplemented option");
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      directory.Clear();
    }

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

    FileSpec directory;
  };

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

protected:
  llvm::Expected<FileSpec> GetDirectory() {
    if (m_options.directory) {
      auto ec =
          llvm::sys::fs::create_directories(m_options.directory.GetPath());
      if (ec)
        return llvm::errorCodeToError(ec);
      return m_options.directory;
    }
    return Diagnostics::CreateUniqueDirectory();
  }

  void DoExecute(Args &args, CommandReturnObject &result) override {
    llvm::Expected<FileSpec> directory = GetDirectory();

    if (!directory) {
      result.AppendError(llvm::toString(directory.takeError()));
      return;
    }

    // Collect the diagnostics bundle into the directory.
    llvm::Expected<Diagnostics::Report> report =
        Diagnostics::Instance().Collect(GetDebugger(), m_exe_ctx, *directory);
    if (!report) {
      result.AppendErrorWithFormat("failed to write diagnostics to %s",
                                   directory->GetPath().c_str());
      result.AppendError(llvm::toString(report.takeError()));
      return;
    }

    // Print the report as JSON so the user can review what a bug report would
    // carry. The bundle directory and its files are listed under "attachments".
    result.GetOutputStream().Format("{0:2}\n", toJSON(*report));

    result.SetStatus(eReturnStatusSuccessFinishResult);
  }

  CommandOptions m_options;
};

class CommandObjectDiagnosticsReport : public CommandObjectParsed {
public:
  CommandObjectDiagnosticsReport(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "diagnostics report",
            "Assemble a diagnostics bundle and file it as a bug report.",
            nullptr) {}

  ~CommandObjectDiagnosticsReport() override = default;

  class CommandOptions : public Options {
  public:
    CommandOptions() = default;

    ~CommandOptions() 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 'd':
        directory.SetDirectory(option_arg);
        break;
      case 'n':
        no_open = true;
        break;
      case 'P':
        plugin = option_arg.str();
        break;
      default:
        llvm_unreachable("Unimplemented option");
      }
      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      directory.Clear();
      no_open = false;
      plugin.clear();
    }

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

    FileSpec directory;
    bool no_open = false;
    std::string plugin;
  };

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

protected:
  llvm::Expected<FileSpec> GetDirectory() {
    if (m_options.directory) {
      auto ec =
          llvm::sys::fs::create_directories(m_options.directory.GetPath());
      if (ec)
        return llvm::errorCodeToError(ec);
      return m_options.directory;
    }
    return Diagnostics::CreateUniqueDirectory();
  }

  void DoExecute(Args &args, CommandReturnObject &result) override {
    llvm::Expected<FileSpec> directory = GetDirectory();
    if (!directory) {
      result.AppendError(llvm::toString(directory.takeError()));
      return;
    }

    llvm::Expected<Diagnostics::Report> report =
        Diagnostics::Instance().Collect(GetDebugger(), m_exe_ctx, *directory);
    if (!report) {
      result.AppendError(llvm::toString(report.takeError()));
      return;
    }

    Stream &out = result.GetOutputStream();
    out << "Bug report written to " << directory->GetPath() << "\n";
    if (!report->attachments.files.empty()) {
      out << "Attach the following files to the issue:\n";
      for (const std::string &file : report->attachments.files)
        out << "  [ ] " << file << "\n";
    }
    out << "Complete the report before sharing it:\n";
    out << "  [ ] Give the report a descriptive title\n";
    out << "  [ ] Answer the questions\n";
    result.AppendWarning("the report may contain file paths, command history "
                         "and program data. Review it before attaching it to a "
                         "public issue");

    if (m_options.no_open) {
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return;
    }

    // No-tracker handling lives in the fallback reporter's File(), not here.
    std::unique_ptr<BugReporter> reporter =
        PluginManager::CreateBugReporterInstance(m_options.plugin);
    if (!reporter) {
      if (!m_options.plugin.empty())
        result.AppendErrorWithFormat("no bug reporter named '%s'",
                                     m_options.plugin.c_str());
      else
        result.AppendError("no bug reporter is available");
      return;
    }
    if (llvm::Error error = reporter->File(*report)) {
      result.AppendError(llvm::toString(std::move(error)));
      return;
    }

    out << "Opened a pre-filled " << reporter->GetPluginName() << " report.\n";
    result.SetStatus(eReturnStatusSuccessFinishResult);
  }

  CommandOptions m_options;
};

CommandObjectDiagnostics::CommandObjectDiagnostics(
    CommandInterpreter &interpreter)
    : CommandObjectMultiword(interpreter, "diagnostics",
                             "Commands controlling LLDB diagnostics.",
                             "diagnostics <subcommand> [<command-options>]") {
  LoadSubCommand(
      "dump", CommandObjectSP(new CommandObjectDiagnosticsDump(interpreter)));
  LoadSubCommand("report", CommandObjectSP(new CommandObjectDiagnosticsReport(
                               interpreter)));
}

CommandObjectDiagnostics::~CommandObjectDiagnostics() = default;
