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

#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb;
using namespace lldb_private;

// CommandObjectQuit

CommandObjectQuit::CommandObjectQuit(CommandInterpreter &interpreter)
    : CommandObjectParsed(interpreter, "quit", "Quit the LLDB debugger.",
                          "quit [exit-code]") {}

CommandObjectQuit::~CommandObjectQuit() = default;

// returns true if there is at least one alive process is_a_detach will be true
// if all alive processes will be detached when you quit and false if at least
// one process will be killed instead
bool CommandObjectQuit::ShouldAskForConfirmation(bool &is_a_detach) {
  if (!m_interpreter.GetPromptOnQuit())
    return false;
  bool should_prompt = false;
  is_a_detach = true;
  for (uint32_t debugger_idx = 0; debugger_idx < Debugger::GetNumDebuggers();
       debugger_idx++) {
    DebuggerSP debugger_sp(Debugger::GetDebuggerAtIndex(debugger_idx));
    if (!debugger_sp)
      continue;
    const TargetList &target_list(debugger_sp->GetTargetList());
    for (uint32_t target_idx = 0;
         target_idx < static_cast<uint32_t>(target_list.GetNumTargets());
         target_idx++) {
      TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
      if (!target_sp)
        continue;
      ProcessSP process_sp(target_sp->GetProcessSP());
      if (process_sp && process_sp->IsValid() && process_sp->IsAlive() &&
          process_sp->WarnBeforeDetach()) {
        should_prompt = true;
        if (!process_sp->GetShouldDetach()) {
          // if we need to kill at least one process, just say so and return
          is_a_detach = false;
          return should_prompt;
        }
      }
    }
  }
  return should_prompt;
}

bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) {
  bool is_a_detach = true;
  if (ShouldAskForConfirmation(is_a_detach)) {
    StreamString message;
    message.Printf("Quitting LLDB will %s one or more processes. Do you really "
                   "want to proceed",
                   (is_a_detach ? "detach from" : "kill"));
    if (!m_interpreter.Confirm(message.GetString(), true)) {
      result.SetStatus(eReturnStatusFailed);
      return false;
    }
  }

  if (command.GetArgumentCount() > 1) {
    result.AppendError("Too many arguments for 'quit'. Only an optional exit "
                       "code is allowed");
    return false;
  }

  // We parse the exit code argument if there is one.
  if (command.GetArgumentCount() == 1) {
    llvm::StringRef arg = command.GetArgumentAtIndex(0);
    int exit_code;
    if (arg.getAsInteger(/*autodetect radix*/ 0, exit_code)) {
      lldb_private::StreamString s;
      std::string arg_str = arg.str();
      s.Printf("Couldn't parse '%s' as integer for exit code.", arg_str.data());
      result.AppendError(s.GetString());
      return false;
    }
    if (!m_interpreter.SetQuitExitCode(exit_code)) {
      result.AppendError("The current driver doesn't allow custom exit codes"
                         " for the quit command.");
      return false;
    }
  }

  const uint32_t event_type =
      CommandInterpreter::eBroadcastBitQuitCommandReceived;
  m_interpreter.BroadcastEvent(event_type);
  result.SetStatus(eReturnStatusQuit);

  return true;
}
