//===-- CommandObjectReproducer.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 "CommandObjectReproducer.h"

#include "lldb/Host/HostInfo.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/Utility/GDBRemote.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Reproducer.h"

#include <csignal>

using namespace lldb;
using namespace llvm;
using namespace lldb_private;
using namespace lldb_private::repro;

#define LLDB_OPTIONS_reproducer_dump
#include "CommandOptions.inc"

#define LLDB_OPTIONS_reproducer_xcrash
#include "CommandOptions.inc"

#define LLDB_OPTIONS_reproducer_verify
#include "CommandOptions.inc"

template <typename T>
llvm::Expected<T> static ReadFromYAML(StringRef filename) {
  auto error_or_file = MemoryBuffer::getFile(filename);
  if (auto err = error_or_file.getError()) {
    return errorCodeToError(err);
  }

  T t;
  yaml::Input yin((*error_or_file)->getBuffer());
  yin >> t;

  if (auto err = yin.error()) {
    return errorCodeToError(err);
  }

  return t;
}

static void SetError(CommandReturnObject &result, Error err) {
  result.AppendError(toString(std::move(err)));
}

/// Create a loader from the given path if specified. Otherwise use the current
/// loader used for replay.
static Loader *
GetLoaderFromPathOrCurrent(llvm::Optional<Loader> &loader_storage,
                           CommandReturnObject &result,
                           FileSpec reproducer_path) {
  if (reproducer_path) {
    loader_storage.emplace(reproducer_path);
    Loader *loader = &(*loader_storage);
    if (Error err = loader->LoadIndex()) {
      // This is a hard error and will set the result to eReturnStatusFailed.
      SetError(result, std::move(err));
      return nullptr;
    }
    return loader;
  }

  if (Loader *loader = Reproducer::Instance().GetLoader())
    return loader;

  // This is a soft error because this is expected to fail during capture.
  result.AppendError(
      "Not specifying a reproducer is only support during replay.");
  result.SetStatus(eReturnStatusSuccessFinishNoResult);
  return nullptr;
}

class CommandObjectReproducerGenerate : public CommandObjectParsed {
public:
  CommandObjectReproducerGenerate(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "reproducer generate",
            "Generate reproducer on disk. When the debugger is in capture "
            "mode, this command will output the reproducer to a directory on "
            "disk and quit. In replay mode this command in a no-op.",
            nullptr) {}

  ~CommandObjectReproducerGenerate() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    auto &r = Reproducer::Instance();
    if (auto generator = r.GetGenerator()) {
      generator->Keep();
    } else {
      result.AppendErrorWithFormat("Unable to get the reproducer generator");
      return false;
    }

    result.GetOutputStream()
        << "Reproducer written to '" << r.GetReproducerPath() << "'\n";
    result.GetOutputStream()
        << "Please have a look at the directory to assess if you're willing to "
           "share the contained information.\n";

    m_interpreter.BroadcastEvent(
        CommandInterpreter::eBroadcastBitQuitCommandReceived);
    result.SetStatus(eReturnStatusQuit);
    return result.Succeeded();
  }
};

class CommandObjectReproducerXCrash : public CommandObjectParsed {
public:
  CommandObjectReproducerXCrash(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "reproducer xcrash",
                            "Intentionally force  the debugger to crash in "
                            "order to trigger and test reproducer generation.",
                            nullptr) {}

  ~CommandObjectReproducerXCrash() override = default;

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

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

    ~CommandOptions() override = default;

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

      switch (short_option) {
      case 's':
        signal = (ReproducerCrashSignal)OptionArgParser::ToOptionEnum(
            option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
        if (!error.Success())
          error.SetErrorStringWithFormat("unrecognized value for signal '%s'",
                                         option_arg.str().c_str());
        break;
      default:
        llvm_unreachable("Unimplemented option");
      }

      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      signal = eReproducerCrashSigsegv;
    }

    ArrayRef<OptionDefinition> GetDefinitions() override {
      return makeArrayRef(g_reproducer_xcrash_options);
    }

    ReproducerCrashSignal signal = eReproducerCrashSigsegv;
  };

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    auto &r = Reproducer::Instance();

    if (!r.IsCapturing()) {
      result.AppendError(
          "forcing a crash is only supported when capturing a reproducer.");
      result.SetStatus(eReturnStatusSuccessFinishNoResult);
      return false;
    }

    switch (m_options.signal) {
    case eReproducerCrashSigill:
      std::raise(SIGILL);
      break;
    case eReproducerCrashSigsegv:
      std::raise(SIGSEGV);
      break;
    }

    result.SetStatus(eReturnStatusQuit);
    return result.Succeeded();
  }

private:
  CommandOptions m_options;
};

class CommandObjectReproducerStatus : public CommandObjectParsed {
public:
  CommandObjectReproducerStatus(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "reproducer status",
            "Show the current reproducer status. In capture mode the "
            "debugger "
            "is collecting all the information it needs to create a "
            "reproducer.  In replay mode the reproducer is replaying a "
            "reproducer. When the reproducers are off, no data is collected "
            "and no reproducer can be generated.",
            nullptr) {}

  ~CommandObjectReproducerStatus() override = default;

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    auto &r = Reproducer::Instance();
    if (r.IsCapturing()) {
      result.GetOutputStream() << "Reproducer is in capture mode.\n";
      result.GetOutputStream()
          << "Path: " << r.GetReproducerPath().GetPath() << '\n';
    } else {
      result.GetOutputStream() << "Reproducer is off.\n";
    }

    // Auto generate is hidden unless enabled because this is mostly for
    // development and testing.
    if (Generator *g = r.GetGenerator()) {
      if (g->IsAutoGenerate())
        result.GetOutputStream() << "Auto generate: on\n";
    }

    result.SetStatus(eReturnStatusSuccessFinishResult);
    return result.Succeeded();
  }
};

class CommandObjectReproducerDump : public CommandObjectParsed {
public:
  CommandObjectReproducerDump(CommandInterpreter &interpreter)
      : CommandObjectParsed(interpreter, "reproducer dump",
                            "Dump the information contained in a reproducer. "
                            "If no reproducer is specified during replay, it "
                            "dumps the content of the current reproducer.",
                            nullptr) {}

  ~CommandObjectReproducerDump() override = default;

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

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

    ~CommandOptions() override = default;

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

      switch (short_option) {
      case 'f':
        file.SetFile(option_arg, FileSpec::Style::native);
        FileSystem::Instance().Resolve(file);
        break;
      case 'p':
        provider = (ReproducerProvider)OptionArgParser::ToOptionEnum(
            option_arg, GetDefinitions()[option_idx].enum_values, 0, error);
        if (!error.Success())
          error.SetErrorStringWithFormat("unrecognized value for provider '%s'",
                                         option_arg.str().c_str());
        break;
      default:
        llvm_unreachable("Unimplemented option");
      }

      return error;
    }

    void OptionParsingStarting(ExecutionContext *execution_context) override {
      file.Clear();
      provider = eReproducerProviderNone;
    }

    ArrayRef<OptionDefinition> GetDefinitions() override {
      return makeArrayRef(g_reproducer_dump_options);
    }

    FileSpec file;
    ReproducerProvider provider = eReproducerProviderNone;
  };

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    llvm::Optional<Loader> loader_storage;
    Loader *loader =
        GetLoaderFromPathOrCurrent(loader_storage, result, m_options.file);
    if (!loader)
      return false;

    switch (m_options.provider) {
    case eReproducerProviderFiles: {
      FileSpec vfs_mapping = loader->GetFile<FileProvider::Info>();

      // Read the VFS mapping.
      ErrorOr<std::unique_ptr<MemoryBuffer>> buffer =
          vfs::getRealFileSystem()->getBufferForFile(vfs_mapping.GetPath());
      if (!buffer) {
        SetError(result, errorCodeToError(buffer.getError()));
        return false;
      }

      // Initialize a VFS from the given mapping.
      IntrusiveRefCntPtr<vfs::FileSystem> vfs = vfs::getVFSFromYAML(
          std::move(buffer.get()), nullptr, vfs_mapping.GetPath());

      // Dump the VFS to a buffer.
      std::string str;
      raw_string_ostream os(str);
      static_cast<vfs::RedirectingFileSystem &>(*vfs).print(os);
      os.flush();

      // Return the string.
      result.AppendMessage(str);
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderSymbolFiles: {
      Expected<std::string> symbol_files =
          loader->LoadBuffer<SymbolFileProvider>();
      if (!symbol_files) {
        SetError(result, symbol_files.takeError());
        return false;
      }

      std::vector<SymbolFileProvider::Entry> entries;
      llvm::yaml::Input yin(*symbol_files);
      yin >> entries;

      for (const auto &entry : entries) {
        result.AppendMessageWithFormat("- uuid:        %s\n",
                                       entry.uuid.c_str());
        result.AppendMessageWithFormat("  module path: %s\n",
                                       entry.module_path.c_str());
        result.AppendMessageWithFormat("  symbol path: %s\n",
                                       entry.symbol_path.c_str());
      }
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderVersion: {
      Expected<std::string> version = loader->LoadBuffer<VersionProvider>();
      if (!version) {
        SetError(result, version.takeError());
        return false;
      }
      result.AppendMessage(*version);
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderWorkingDirectory: {
      Expected<std::string> cwd =
          repro::GetDirectoryFrom<WorkingDirectoryProvider>(loader);
      if (!cwd) {
        SetError(result, cwd.takeError());
        return false;
      }
      result.AppendMessage(*cwd);
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderHomeDirectory: {
      Expected<std::string> home =
          repro::GetDirectoryFrom<HomeDirectoryProvider>(loader);
      if (!home) {
        SetError(result, home.takeError());
        return false;
      }
      result.AppendMessage(*home);
      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderCommands: {
      std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> multi_loader =
          repro::MultiLoader<repro::CommandProvider>::Create(loader);
      if (!multi_loader) {
        SetError(result,
                 make_error<StringError>("Unable to create command loader.",
                                         llvm::inconvertibleErrorCode()));
        return false;
      }

      // Iterate over the command files and dump them.
      llvm::Optional<std::string> command_file;
      while ((command_file = multi_loader->GetNextFile())) {
        if (!command_file)
          break;

        auto command_buffer = llvm::MemoryBuffer::getFile(*command_file);
        if (auto err = command_buffer.getError()) {
          SetError(result, errorCodeToError(err));
          return false;
        }
        result.AppendMessage((*command_buffer)->getBuffer());
      }

      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderGDB: {
      std::unique_ptr<repro::MultiLoader<repro::GDBRemoteProvider>>
          multi_loader =
              repro::MultiLoader<repro::GDBRemoteProvider>::Create(loader);

      if (!multi_loader) {
        SetError(result,
                 make_error<StringError>("Unable to create GDB loader.",
                                         llvm::inconvertibleErrorCode()));
        return false;
      }

      llvm::Optional<std::string> gdb_file;
      while ((gdb_file = multi_loader->GetNextFile())) {
        if (llvm::Expected<std::vector<GDBRemotePacket>> packets =
                ReadFromYAML<std::vector<GDBRemotePacket>>(*gdb_file)) {
          for (GDBRemotePacket &packet : *packets) {
            packet.Dump(result.GetOutputStream());
          }
        } else {
          SetError(result, packets.takeError());
          return false;
        }
      }

      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderProcessInfo: {
      std::unique_ptr<repro::MultiLoader<repro::ProcessInfoProvider>>
          multi_loader =
              repro::MultiLoader<repro::ProcessInfoProvider>::Create(loader);

      if (!multi_loader) {
        SetError(result, make_error<StringError>(
                             llvm::inconvertibleErrorCode(),
                             "Unable to create process info loader."));
        return false;
      }

      llvm::Optional<std::string> process_file;
      while ((process_file = multi_loader->GetNextFile())) {
        if (llvm::Expected<ProcessInstanceInfoList> infos =
                ReadFromYAML<ProcessInstanceInfoList>(*process_file)) {
          for (ProcessInstanceInfo info : *infos)
            info.Dump(result.GetOutputStream(), HostInfo::GetUserIDResolver());
        } else {
          SetError(result, infos.takeError());
          return false;
        }
      }

      result.SetStatus(eReturnStatusSuccessFinishResult);
      return true;
    }
    case eReproducerProviderNone:
      result.AppendError("No valid provider specified.");
      return false;
    }

    result.SetStatus(eReturnStatusSuccessFinishNoResult);
    return result.Succeeded();
  }

private:
  CommandOptions m_options;
};

CommandObjectReproducer::CommandObjectReproducer(
    CommandInterpreter &interpreter)
    : CommandObjectMultiword(
          interpreter, "reproducer",
          "Commands for manipulating reproducers. Reproducers make it "
          "possible "
          "to capture full debug sessions with all its dependencies. The "
          "resulting reproducer is used to replay the debug session while "
          "debugging the debugger.\n"
          "Because reproducers need the whole the debug session from "
          "beginning to end, you need to launch the debugger in capture or "
          "replay mode, commonly though the command line driver.\n"
          "Reproducers are unrelated record-replay debugging, as you cannot "
          "interact with the debugger during replay.\n",
          "reproducer <subcommand> [<subcommand-options>]") {
  LoadSubCommand(
      "generate",
      CommandObjectSP(new CommandObjectReproducerGenerate(interpreter)));
  LoadSubCommand("status", CommandObjectSP(
                               new CommandObjectReproducerStatus(interpreter)));
  LoadSubCommand("dump",
                 CommandObjectSP(new CommandObjectReproducerDump(interpreter)));
  LoadSubCommand("xcrash", CommandObjectSP(
                               new CommandObjectReproducerXCrash(interpreter)));
}

CommandObjectReproducer::~CommandObjectReproducer() = default;
