//===-- CommandObjectBugreport.cpp ------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "CommandObjectBugreport.h"

// C Includes
#include <cstdio>

// C++ Includes
// Other libraries and framework includes

// Project includes
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupOutputFile.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

//-------------------------------------------------------------------------
// "bugreport unwind"
//-------------------------------------------------------------------------

class CommandObjectBugreportUnwind : public CommandObjectParsed {
public:
  CommandObjectBugreportUnwind(CommandInterpreter &interpreter)
      : CommandObjectParsed(
            interpreter, "bugreport unwind",
            "Create a bugreport for a bug in the stack unwinding code.",
            nullptr),
        m_option_group(), m_outfile_options() {
    m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL,
                          LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
    m_option_group.Finalize();
  }

  ~CommandObjectBugreportUnwind() override {}

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

protected:
  bool DoExecute(Args &command, CommandReturnObject &result) override {
    StringList commands;
    commands.AppendString("thread backtrace");

    Thread *thread = m_exe_ctx.GetThreadPtr();
    if (thread) {
      char command_buffer[256];

      uint32_t frame_count = thread->GetStackFrameCount();
      for (uint32_t i = 0; i < frame_count; ++i) {
        StackFrameSP frame = thread->GetStackFrameAtIndex(i);
        lldb::addr_t pc = frame->GetStackID().GetPC();

        snprintf(command_buffer, sizeof(command_buffer),
                 "disassemble --bytes --address 0x%" PRIx64, pc);
        commands.AppendString(command_buffer);

        snprintf(command_buffer, sizeof(command_buffer),
                 "image show-unwind --address 0x%" PRIx64, pc);
        commands.AppendString(command_buffer);
      }
    }

    const FileSpec &outfile_spec =
        m_outfile_options.GetFile().GetCurrentValue();
    if (outfile_spec) {
      char path[PATH_MAX];
      outfile_spec.GetPath(path, sizeof(path));

      uint32_t open_options =
          File::eOpenOptionWrite | File::eOpenOptionCanCreate |
          File::eOpenOptionAppend | File::eOpenOptionCloseOnExec;

      const bool append = m_outfile_options.GetAppend().GetCurrentValue();
      if (!append)
        open_options |= File::eOpenOptionTruncate;

      StreamFileSP outfile_stream = std::make_shared<StreamFile>();
      Status error = outfile_stream->GetFile().Open(path, open_options);
      if (error.Fail()) {
        result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n",
                                     path, append ? "append" : "write",
                                     error.AsCString());
        result.SetStatus(eReturnStatusFailed);
        return false;
      }

      result.SetImmediateOutputStream(outfile_stream);
    }

    CommandInterpreterRunOptions options;
    options.SetStopOnError(false);
    options.SetEchoCommands(true);
    options.SetPrintResults(true);
    options.SetAddToHistory(false);
    m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result);

    return result.Succeeded();
  }

private:
  OptionGroupOptions m_option_group;
  OptionGroupOutputFile m_outfile_options;
};

#pragma mark CommandObjectMultiwordBugreport

//-------------------------------------------------------------------------
// CommandObjectMultiwordBugreport
//-------------------------------------------------------------------------

CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(
    CommandInterpreter &interpreter)
    : CommandObjectMultiword(
          interpreter, "bugreport",
          "Commands for creating domain-specific bug reports.",
          "bugreport <subcommand> [<subcommand-options>]") {

  LoadSubCommand(
      "unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter)));
}

CommandObjectMultiwordBugreport::~CommandObjectMultiwordBugreport() {}
