// 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_display.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/system.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/print_command_utils.h"
#include "src/developer/debug/zxdb/console/verbs.h"

namespace zxdb {

namespace {

const char kDisplayShortHelp[] = "display: Print an expression on every stop.";
const char kDisplayHelp[] =
    R"(display <expression>

  Adds the given expression to the global list that will be evaluated and
  printed for every stop.

The "display" setting

  This command is syntactic sugar for the settings system where the setting
  named "display" keeps this information. Use the settings system to view or
  remove expressions (there is no "undisplay" command).

  The settings system is hierarchical (see "help get" for more) so there are
  global, process, and thread-specific display lists. The most specific nonempty
  list will be used when a thread stops.

  For more complex ways to modify the display list, use the settings system (see
  "help set"). Note that expressions with spaces will need to be quoted when
  used with the settings system, but this is not necessary when using the
  "display" verb since it can only add one expression at a time.

Examples

  display foo->bar
  set display += "foo->bar"
  global set display += "foo->bar"
      These commands are equivalent to add the expression to the global
      "display" list.

  get display
      Prints the current thread's "display" list. This will fall back on the
      process' list, and then on the global list if unset.

  set display=
      Clears all variables from the global display list.

  set display -= "foo->bar"
      Removes the given expression from the display list, keeping others the
      same.

  thread set display += i
  thread get display
  thread set display -= i
  thread set display =
      Adds, prints, removes, and clears the thread-specific display list. These
      are the same as the above examples but with "thread" added to the
      beginning. If there is a thread-specific display list, it will take effect
      whenever that thread stops instead of process or global ones.

  process set display = i j "foo->bar"
      Overwrites all contents of the process-specific display list to print the
      given three expressions. The process list will take effect when the
      process stops and there is no thread-specific one.
)";

const char kCommandHelp[] =
    " • View current list: get display\n"
    " • Remove one:        set display -= your_var\n"
    " • Clear list:        set display =\n";

Err RunVerbDisplay(ConsoleContext* context, const Command& cmd) {
  if (cmd.args().size() != 1) {
    // We could print the current list fo stuff to display here like GDB, but would prefer that
    // people learn to interact with the settings system since they'll need that to remove values
    // anyway.
    return Err(
        "The \"display\" verb is syntactic sugar for the settings system's \"display\"\n"
        "setting. It's a shortcut to add expressions to display, but otherwise use the\n"
        "settings commands:\n" +
        std::string(kCommandHelp));
  }

  // The thing to watch. Note that we can't actually validate this here because the expression might
  // only be valid in a different context.
  const std::string& new_expression = cmd.args()[0];

  SettingStore* store = &context->session()->system().settings();

  // Be nice and avoid duplicating an expression.
  std::vector<std::string> list = store->GetList(ClientSettings::Thread::kDisplay);
  for (const auto& existing : list) {
    if (new_expression == existing)
      return Err("Already watching expression \"" + new_expression + "\".");
  }

  list.push_back(new_expression);
  store->SetList(ClientSettings::Thread::kDisplay, list);

  OutputBuffer out("Added to display for every stop: ");
  out.Append(Syntax::kHeading, new_expression);
  out.Append("\n");
  out.Append(Syntax::kComment, kCommandHelp);

  Console::get()->Output(out);

  // Output the new expression right away.
  ConsoleFormatOptions options;
  options.verbosity = ConsoleFormatOptions::Verbosity::kMinimal;
  options.wrapping = ConsoleFormatOptions::Wrapping::kSmart;
  options.pointer_expand_depth = 2;
  Console::get()->Output(
      FormatExpressionsForConsole({new_expression}, options, GetEvalContextForCommand(cmd)));

  return Err();
}

}  // namespace

VerbRecord GetDisplayVerbRecord() {
  VerbRecord record(&RunVerbDisplay, {"display"}, kDisplayShortHelp, kDisplayHelp,
                    CommandGroup::kQuery);
  record.param_type = VerbRecord::kOneParam;  // Allows arbitrary unquoted input.
  return record;
}

}  // namespace zxdb
