// Copyright 2020 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_continue.h"

#include "src/developer/debug/zxdb/client/process.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/setting_schema_definition.h"
#include "src/developer/debug/zxdb/client/target.h"
#include "src/developer/debug/zxdb/client/thread.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/output_buffer.h"
#include "src/developer/debug/zxdb/console/verbs.h"

namespace zxdb {

namespace {

constexpr int kForwardSwitchID = 0;

const char kContinueShortHelp[] = "continue / c: Continue a suspended thread or process.";
const char kContinueUsage[] = "continue / c [ --forward / -f ]";
const char kContinueHelp[] = R"(
  When a thread is stopped at an exception or a breakpoint, "continue" will
  continue the execution.

  See "pause" to stop a running thread or process.

  The behavior will depend upon the context specified.

  - By itself, "continue" will continue all threads of all processes that are
    currently stopped.

  - When a process is specified ("process 2 continue" for an explicit process
    or "process continue" for the current process), only the threads in that
    process will be continued. Other debugged processes currently stopped will
    remain so.

  - When a thread is specified ("thread 1 continue" for an explicit thread
    or "thread continue" for the current thread), only that thread will be
    continued. Other threads in that process and other processes currently
    stopped will remain so.

  TODO(brettw) it might be nice to have a --other flag that would continue
  all threads other than the specified one (which the user might want to step
  while everything else is going).

Options

  --forward | -f
      This is a directive that the relevant exception(s) should not be marked
      as handled, but rather forwarded as 'second-chance' in which the
      process-level handler is given a chance to resolve the exception before
      the debugger inspects it again.

Examples

  c
  c -f
  continue
  continue --forward
      Continue all processes and threads.

  pr c
  process continue
  process 4 continue
      Continue all threads of a process (the current process is implicit if
      no process index is specified).

  t c
  t c -f
  thread continue
  thread continue --forward
  pr -f
  pr 2 t 4 c
  process 2 thread 4 continue
      Continue only one thread (the current process and thread are implicit
      if no index is specified).
)";

void RunVerbContinue(const Command& cmd, fxl::RefPtr<CommandContext> cmd_context) {
  if (Err err = cmd.ValidateNouns({Noun::kGlobal, Noun::kProcess, Noun::kThread}); err.has_error())
    return cmd_context->ReportError(err);

  bool forward = cmd.HasSwitch(kForwardSwitchID);

  // Should always be present because we were called synchronously.
  ConsoleContext* console_context = cmd_context->GetConsoleContext();

  if (cmd.HasNoun(Noun::kThread)) {
    cmd.thread()->Continue(forward);
  } else if (cmd.HasNoun(Noun::kProcess)) {
    Process* process = cmd.target()->GetProcess();
    if (!process)
      return cmd_context->ReportError(Err("Process not running, can't continue."));
    process->Continue(forward);
  } else {
    if (Err err = VerifySystemHasRunningProcess(&console_context->session()->system());
        err.has_error()) {
      return cmd_context->ReportError(err);
    }
    console_context->session()->system().Continue(forward);
  }
}

}  // namespace

VerbRecord GetContinueVerbRecord() {
  VerbRecord record{
      &RunVerbContinue, {"continue", "cont", "c"}, kContinueShortHelp,     kContinueUsage,
      kContinueHelp,    CommandGroup::kStep,       SourceAffinity::kSource};
  record.switches.emplace_back(kForwardSwitchID, false, "forward", 'f');
  return record;
}

}  // namespace zxdb
