text: // 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/client/session.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/format_job.h"
  #include "src/developer/debug/zxdb/console/format_target.h"
  #include "src/developer/debug/zxdb/console/verbs.h"
  
  namespace zxdb {
  
  namespace {
  
  // new -------------------------------------------------------------------------
  
  const char kNewShortHelp[] = "new: Create a new process/job context.";
  const char kNewHelp[] =
      R"(new
  
    Creates a new process/job context.
  
    A process context holds settings (binary name, command line arguments, etc.)
    and possibly a running process. The new context will have no associated
    process and can then be run or attached.
  
    A job context holds settings (filters, etc.)
    and possibly a running job. The new context will have no associated
    job and can then be run or attached.
  
    The settings from the current process/job context will be cloned. If an explicit
    process/job is specified ("process 2 new"), the new process/job context will clone
    the given one. The new context will be the active context.
  
    A process/job noun must be specified. Long-term we want to add support to "new"
    multiple things.
  
  Hints
  
    To see a list of available process/job contexts, type "process" or "job". To switch the
    active process context, specify its index ("(process|job) 3").
  
  Example
  
    This example creates two processes, a "chrome" process, and attaches to
    some existing process.
  
    [zxdb] run chrome
    Process 1 Running 3456 chrome
    [zxdb] process new
    Process 2 created.
    [zxdb] pr attach 1239
    Process 2 Running 1239
  
    This example attaches to some existing job.
    [zxdb] job new
    Job 2 created.
    [zxdb] j attach 1239
    Job 2 Running 1239
  )";
  Err DoNew(ConsoleContext* context, const Command& cmd) {
    Err err = cmd.ValidateNouns({Noun::kProcess, Noun::kJob});
    if (err.has_error())
      return err;
  
    if (!cmd.HasNoun(Noun::kProcess) && !cmd.HasNoun(Noun::kJob))
      return Err("Use \"process new\" or \"job new\" to create a new context.");
  
    if (cmd.HasNoun(Noun::kJob)) {
      JobContext* new_job_context =
          context->session()->system().CreateNewJobContext(cmd.job_context());
      context->SetActiveJobContext(new_job_context);
      Console::get()->Output(FormatJobContext(context, new_job_context));
    } else {
      Target* new_target = context->session()->system().CreateNewTarget(cmd.target());
      context->SetActiveTarget(new_target);
      Console::get()->Output(FormatTarget(context, new_target));
    }
    return Err();
  }
  
  // rm --------------------------------------------------------------------------
  
  const char kRmShortHelp[] = "rm: Remove a filter.";
  const char kRmHelp[] =
      R"(rm
  
    Removes a filter. You must specify the filter explicitly to delete it.
  
    Filters can be added with the attach command.
  
  Hints
  
    To see a list of available filters, type "filter".
  
  Example
  
    filter 3 rm
        Remove filter number 3.
  )";
  Err DoRm(ConsoleContext* context, const Command& cmd) {
    Err err = cmd.ValidateNouns({Noun::kFilter});
    if (err.has_error())
      return err;
  
    if (!cmd.HasNoun(Noun::kFilter) || cmd.GetNounIndex(Noun::kFilter) == Command::kNoIndex)
      return Err("You must explicitly specify \"filter n rm\" to remove a filter.");
  
    context->session()->system().DeleteFilter(cmd.filter());
  
    return Err();
  }
  
  }  // namespace
  
  void AppendSharedVerbs(std::map<Verb, VerbRecord>* verbs) {
    (*verbs)[Verb::kNew] =
        VerbRecord(&DoNew, {"new"}, kNewShortHelp, kNewHelp, CommandGroup::kGeneral);
    (*verbs)[Verb::kRm] = VerbRecord(&DoRm, {"rm"}, kRmShortHelp, kRmHelp, CommandGroup::kGeneral);
  }
  
  }  // namespace zxdb
  