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

#include <lib/syslog/cpp/macros.h>

#include "src/developer/debug/shared/zx_status.h"
#include "src/developer/debug/zxdb/client/remote_api.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/target.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 {

constexpr int kRunComponentSwitch = 1;

const char kRunShortHelp[] = "run / r: Run the program.";
const char kRunHelp[] =
    R"(run [--component] [ <program name> <program args>* ]

  Alias: "r"

  Runs the program. With no arguments, "run" will run the binary stored in the
  process context, if any. With an argument, the binary name will be set and
  that binary will be run.

Why "run" is usually wrong

  The following loader environments all have different capabilities (in order
  from least capable to most capable):

    • The debugger's "run <file name>" command (base system process stuff).
    • The system console or "fx shell" (adds some libraries).
    • The base component environment via the shell‘s run and the debugger’s
      "run -c <package url>" (adds component capabilities).
    • The test environment via "fx test".
    • The user environment when launched from a “story” (adds high-level
      services like scenic).

  This panoply of environments is why the debugger can't have a simple “run”
  command that always works.

  When the debugger launches a process or a component, that process or
  component will have the same capabilities as the debug_agent running on the
  system. Whether this is enough to run a specific process or component is
  mostly accidental.

  The only way to get the correct environment is to launch your process or
  component in the way it expects and attach the debugger to it. Filters
  allow you to attach to a new process as it's created to debug from the
  beginning. A typical flow is:

    # Register for the process name. Use the name that appears in "ps" for
    # the process:
    [zxdb] attach my_app_name
    Waiting for process matching "my_app_name"

    # Set a pending breakpoint to stop where you want:
    [zxdb] break main
    Breakpoint 1 (Software) on Global, Enabled, stop=All, @ main
    Pending: No matches for location, it will be pending library loads.

    # Launch your app like normal, the debugger should catch it:
    Attached Process 1 [Running] koid=33213 debug_agent.cmx
    🛑 on bp 1 main(…) • main.cc:220
       219 ...
     ▶ 220 int main(int argc, const char* argv[]) {
       221 ...

Arguments

  --component | -c
      Run this program as a component. The program name should be a component
      URL. In addition to the above-discussed limitations, the debugger must
      currently be attached to the system root job.

Hints

  By default "run" will run the active process context (create a new one with
  "new" to run multiple programs at once). To run an explicit process context,
  specify it explicitly: "process 2 run".

  To see a list of available process contexts, type "process".

Examples

  run
  process 2 run
      Runs a process that's already been configured with a binary name.

  run /boot/bin/ps
  run chrome --no-sandbox http://www.google.com/
      Runs the given process.
)";

void LaunchComponent(const Command& cmd) {
  debug_ipc::LaunchRequest request;
  request.inferior_type = debug_ipc::InferiorType::kComponent;
  request.argv = cmd.args();

  auto launch_cb = [target = cmd.target()->GetWeakPtr()](const Err& err,
                                                         debug_ipc::LaunchReply reply) {
    if (err.has_error()) {
      Console::get()->Output(err);
      return;
    }
    FX_DCHECK(reply.inferior_type == debug_ipc::InferiorType::kComponent)
        << "Expected Component, Got: " << debug_ipc::InferiorTypeToString(reply.inferior_type);

    if (reply.status.has_error()) {
      // TODO(donosoc): This should interpret the component termination reason values.
      Console::get()->Output(Err("Could not start component %s: %s", reply.process_name.c_str(),
                                 reply.status.message().c_str()));
      return;
    }

    FX_DCHECK(target);

    // We tell the session we will be expecting this component.
    FX_DCHECK(reply.process_id == 0);
    FX_DCHECK(reply.component_id != 0);
    target->session()->ExpectComponent(reply.component_id);
  };

  cmd.target()->session()->remote_api()->Launch(std::move(request), std::move(launch_cb));
}

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

  // May need to create a new target.
  auto err_or_target = GetRunnableTarget(context, cmd);
  if (err_or_target.has_error())
    return err_or_target.err();
  Target* target = err_or_target.value();

  // Output warning about this possibly not working.
  OutputBuffer warning(Syntax::kWarning, GetExclamation());
  warning.Append(
      " Run won't work for many processes and components. "
      "See \"help run\".\n");
  Console::get()->Output(warning);

  if (!cmd.HasSwitch(kRunComponentSwitch)) {
    if (cmd.args().empty()) {
      // Use the args already set on the target.
      if (target->GetArgs().empty())
        return Err("No program to run. Try \"run <program name>\".");
    } else {
      target->SetArgs(cmd.args());
    }

    target->Launch([callback = std::move(callback)](fxl::WeakPtr<Target> target, const Err& err,
                                                    uint64_t timestamp) mutable {
      // The ConsoleContext displays messages for new processes, so don't display messages when
      // successfully starting.
      ProcessCommandCallback(target, false, err, std::move(callback));
    });
  } else {
    LaunchComponent(cmd);
  }

  return Err();
}

}  // namespace

VerbRecord GetRunVerbRecord() {
  VerbRecord run(&RunVerbRun, {"run", "r"}, kRunShortHelp, kRunHelp, CommandGroup::kProcess);
  run.switches.push_back(SwitchRecord(kRunComponentSwitch, false, "component", 'c'));
  return run;
}

}  // namespace zxdb
