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

#include "src/developer/debug/zxdb/client/filter.h"
#include "src/developer/debug/zxdb/client/job.h"
#include "src/developer/debug/zxdb/client/session.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/string_util.h"
#include "src/developer/debug/zxdb/console/verbs.h"

namespace zxdb {

namespace {

const char kAttachShortHelp[] = "attach: Attach to a running process/job.";
const char kAttachHelp[] =
    R"(attach <what>

  Attaches to a current or future process.

Atttaching to a specific process

  To attach to a specific process, supply the process' koid (process ID).
  For example:

    attach 12345

  Use the "ps" command to view the active processes, their names, and koids.

Attaching to processes by name

  Non-numeric arguments will be interpreted as a filter. A filter is a substring
  that matches any part of the process name. The filter "t" will match any
  process with the letter "t" in its name. Filters are not regular expressions.

  Filters are applied to processes launched in jobs the debugger is attached to,
  both current processes and future ones.

  More on jobs:

    • See the currently attached jobs with the "job" command.

    • Attach to a new job with the "attach-job" command.

  More on filters:

    • See the current filters with the "filter" command.

    • Delete a filter with "filter [X] rm" where X is the filter index from the
      "filter" list. If no filter index is provided, the current filter will be
      deleted.

    • Change a filter's pattern with "filter [X] set pattern = <newvalue>".

    • Attach to all processes in a job with "job attach *". Note that * is a
      special string for filters, regular expressions are not supported.

  If a job prefix is specified, only processes launched in that job matching the
  pattern will be attached to:

    job attach foo      // Uses the current job context.
    job 2 attach foo    // Specifies job context #2.

  If you have a specific job koid (12345) and want to watch "foo" processes in
  it, a faster way is:

    attach-job 12345 foo

Examples

  attach 2371
      Attaches to the process with koid 2371.

  process 4 attach 2371
      Attaches process context 4 to the process with koid 2371.

  attach foobar
      Attaches to any process that spawns under any job the debugger is attached
      to with "foobar" in the name.

  job 3 attach foobar
      Attaches to any process that spawns under job 3 with "foobar" in the
      name.
)";

bool HasAttachedJob(const System* system) {
  for (const Job* job : system->GetJobs()) {
    if (job->state() == Job::State::kAttached)
      return true;
  }
  return false;
}

Err RunVerbAttach(ConsoleContext* context, const Command& cmd, CommandCallback callback) {
  // Only a process can be attached.
  if (Err err = cmd.ValidateNouns({Noun::kProcess, Noun::kJob}); err.has_error())
    return err;

  uint64_t koid = 0;
  if (ReadUint64Arg(cmd, 0, "process koid", &koid).ok()) {
    // Check for duplicate koids before doing anything else to avoid creating a container target
    // in this case. It's easy to hit enter twice which will cause a duplicate attach. The
    // duplicate target is the only reason to check here, the attach will fail later if there's
    // a duplicate (say, created in a race condition).
    if (context->session()->system().ProcessFromKoid(koid))
      return Err("Process " + std::to_string(koid) + " is already being debugged.");

    // Attach to a process by KOID.
    auto err_or_target = GetRunnableTarget(context, cmd);
    if (err_or_target.has_error())
      return err_or_target.err();
    err_or_target.value()->Attach(
        koid, [callback = std::move(callback)](fxl::WeakPtr<Target> target, const Err& err,
                                               uint64_t timestamp) mutable {
          // Don't display a message on success because the ConsoleContext will print the new
          // process information when it's detected.
          ProcessCommandCallback(target, false, err, std::move(callback));
        });
    return Err();
  }

  // Not a number, make a filter instead. This only supports only "job" nouns.
  if (cmd.ValidateNouns({Noun::kJob}).has_error()) {
    return Err(
        "Attaching by process name (a non-numeric argument)\nonly supports the \"job\" noun.");
  }
  if (cmd.args().size() != 1)
    return Err("Wrong number of arguments to attach.");

  Job* job = cmd.HasNoun(Noun::kJob) && cmd.job() ? cmd.job() : nullptr;
  std::string pattern = cmd.args()[0];
  if (!job && pattern == Filter::kAllProcessesPattern) {
    // Bad things happen if we try to attach to all processes in the system, try to make this
    // more difficult by preventing attaching to * with no specific job.
    return Err("Use a specific job (\"job 3 attach *\") when attaching to all processes.");
  }

  // Display a warning if there are no attached jobs. The debugger tries to attach to the root job
  // by default but if this fails (say there is more than one debug agent), attach will surprisingly
  // fail.
  if (!HasAttachedJob(&context->session()->system())) {
    OutputBuffer warning;
    warning.Append(Syntax::kWarning, GetExclamation());
    warning.Append(
        " There are currently no attached jobs. This could be because you\n"
        "haven't attached to any, or because auto-attaching to the default jobs\n"
        "failed (this can happen if there are more than one debug agents running).\n"
        "Since attaching by name only applies to attached jobs, nothing will happen\n"
        "until you attach to a job (\"attach-job <job-koid>\").\n\n");
    Console::get()->Output(warning);
  }

  if (pattern.size() > kZirconMaxNameLength) {
    Console::get()->Output(OutputBuffer(
        Syntax::kWarning,
        "The filter is trimmed to " + std::to_string(kZirconMaxNameLength) +
            " characters because it's the maximum length for a process name in Zircon."));
    pattern.resize(kZirconMaxNameLength);
  }

  Filter* filter = context->session()->system().CreateNewFilter();
  filter->SetJob(job);
  filter->SetPattern(pattern);

  context->SetActiveFilter(filter);

  // This doesn't use the default filter formatting to try to make it friendlier for people
  // that are less familiar with the debugger and might be unsure what's happening (this is normally
  // one of the first things people do in the debugger. The filter number is usually not relevant
  // anyway.
  Console::get()->Output("Waiting for process matching \"" + pattern +
                         "\".\n"
                         "Type \"filter\" to see the current filters.");
  if (callback) {
    callback(Err());
  }
  return Err();
}

}  // namespace

VerbRecord GetAttachVerbRecord() {
  VerbRecord attach(&RunVerbAttach, {"attach"}, kAttachShortHelp, kAttachHelp,
                    CommandGroup::kProcess);
  return attach;
}

}  // namespace zxdb
