// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/developer/debug/zxdb/console/commands/verb_quit.h"

#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/setting_schema_definition.h"
#include "src/developer/debug/zxdb/console/command.h"
#include "src/developer/debug/zxdb/console/command_utils.h"
#include "src/developer/debug/zxdb/console/console.h"
#include "src/developer/debug/zxdb/console/console_context.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

constexpr int kForceQuitSwitch = 1;

const char kQuitShortHelp[] = "quit / q / exit: Quits the debugger.";
const char kQuitUsage[] = "quit";
const char kQuitHelp[] =
    R"(quit

  Quits the debugger. It will prompt for confirmation if there are running
  processes.

Options

  -f
  --force
      Quit without prompting, even if a process is attached or in embedded mode.
)";

void RunVerbQuit(const Command& cmd, fxl::RefPtr<CommandContext> cmd_context) {
  if (cmd.HasSwitch(kForceQuitSwitch)) {
    cmd_context->console()->Quit();
    return;
  }

  // When we're in embedded mode, we don't want to actually quit until the streaming fd is closed.
  // Detach from everything and go back to embedded mode.
  if (cmd_context->GetConsoleContext()->GetConsoleMode() ==
      ClientSettings::System::kConsoleMode_EmbeddedInteractive) {
    cmd_context->GetConsoleContext()->session()->system().DetachFromAllTargets(
        [cmd_context](int) {});
    return;
  }

  int running_processes = 0;
  for (Target* t : cmd_context->GetConsoleContext()->session()->system().GetTargets()) {
    if (t->GetState() != Target::kNone)
      running_processes++;
  }

  if (running_processes == 0) {
    // Nothing running, quit immediately.
    cmd_context->console()->Quit();
    return;
  }

  OutputBuffer message;
  if (running_processes == 1) {
    message =
        OutputBuffer("\nAre you sure you want to quit and detach from the running process?\n");
  } else {
    message = OutputBuffer(
        fxl::StringPrintf("\nAre you sure you want to quit and detach from %d running processes?\n",
                          running_processes));
  }

  line_input::ModalPromptOptions options;
  options.require_enter = false;
  options.case_sensitive = false;
  options.options.push_back("y");
  options.options.push_back("n");
  options.cancel_option = "n";
  Console::get()->ModalGetOption(options, message, "y/n > ",
                                 [cmd_context](const std::string& answer) {
                                   if (answer == "y")
                                     cmd_context->console()->Quit();
                                 });
}

}  // namespace

VerbRecord GetQuitVerbRecord() {
  VerbRecord quit(&RunVerbQuit, {"quit", "q", "exit"}, kQuitShortHelp, kQuitUsage, kQuitHelp,
                  CommandGroup::kGeneral);
  quit.switches = {SwitchRecord(kForceQuitSwitch, false, "force", 'f')};
  return quit;
}

}  // namespace zxdb
