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

#include <ctype.h>

#include <algorithm>

#include "src/developer/debug/zxdb/client/breakpoint.h"
#include "src/developer/debug/zxdb/client/execution_scope.h"
#include "src/developer/debug/zxdb/client/filter.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/setting_schema.h"
#include "src/developer/debug/zxdb/client/setting_schema_definition.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/common/adapters.h"
#include "src/developer/debug/zxdb/console/command.h"
#include "src/developer/debug/zxdb/console/command_parser.h"
#include "src/developer/debug/zxdb/console/command_utils.h"
#include "src/developer/debug/zxdb/console/console.h"
#include "src/developer/debug/zxdb/console/format_settings.h"
#include "src/developer/debug/zxdb/console/input_location_parser.h"
#include "src/developer/debug/zxdb/console/nouns.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"
#include "src/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

constexpr int kValueOnlySwitch = 1;

// TODO(brettw) Some of this is very repetitive. The Check*() functions and the big block in
// GetSettingContext() duplicate getting scopes and checking stuff.
//
// It would be nice if this was expressed in more of a table form to eliminate this code. The
// Level enum could also be removed if the setting store description could be added to the
// SettingContext.

// Struct to represents all the context needed to correctly reason about the settings commands.
struct SettingContext {
  enum class Level {
    kGlobal,
    kTarget,
    kThread,
    kBreakpoint,
    kFilter,
  };

  // The SettingStore we're using. This will either be the one the user specified or the implicit
  // one deteched for the value. It will be null if the name is empty and there was no explicitly
  // specified one.
  SettingStore* store = nullptr;

  // Set when the user has explicitly set the setting store ("thread 1 set ..."). False means the
  // store was determined implicitly based on the name.
  bool explicit_store = false;

  std::string name;
  SettingValue value;

  // At what level the setting was applied.
  Level level = Level::kGlobal;

  // What kind of operation this is for set commands.
  ParsedSetCommand::Operation op = ParsedSetCommand::kAssign;
};

// Fixes up user typing for a setting name by lower-casing.
std::string CanonicalizeSettingName(const std::string& input) {
  std::string output;
  output.reserve(input.size());
  for (char c : input)
    output.push_back(tolower(c));
  return output;
}

bool CheckGlobal(ConsoleContext* context, const Command& cmd, const std::string& setting_name,
                 SettingContext* out) {
  if (!context->session()->system().settings().schema()->HasSetting(setting_name))
    return false;
  out->store = &context->session()->system().settings();
  out->level = SettingContext::Level::kGlobal;
  return true;
}

bool CheckTarget(ConsoleContext* context, const Command& cmd, const std::string& setting_name,
                 SettingContext* out) {
  if (!cmd.target()->settings().schema()->HasSetting(setting_name))
    return false;
  out->store = &cmd.target()->settings();
  out->level = SettingContext::Level::kTarget;
  return true;
}

bool CheckThread(ConsoleContext* context, const Command& cmd, const std::string& setting_name,
                 SettingContext* out) {
  if (!cmd.thread() || !cmd.thread()->settings().schema()->HasSetting(setting_name))
    return false;
  out->store = &cmd.thread()->settings();
  out->level = SettingContext::Level::kThread;
  return true;
}

// Applies the hierarchical rules for getting/setting a setting and fills the give SettingContext.
// It takes into account the noun overrides.
Err GetSettingContext(ConsoleContext* context, const Command& cmd, const std::string& setting_name,
                      SettingContext* out) {
  if (!cmd.target())
    return Err("No process found. Please file a bug with a repro.");

  out->name = CanonicalizeSettingName(setting_name);

  // Handle noun overrides for getting/setting on specific objects.
  // TODO(brettw) see above for TODO about reducing this duplication.
  if (cmd.HasNoun(Noun::kThread)) {
    out->store = cmd.thread() ? &cmd.thread()->settings() : nullptr;
    out->explicit_store = true;
    out->level = SettingContext::Level::kThread;
  } else if (cmd.HasNoun(Noun::kProcess)) {
    out->store = &cmd.target()->settings();
    out->explicit_store = true;
    out->level = SettingContext::Level::kTarget;
  } else if (cmd.HasNoun(Noun::kGlobal)) {
    out->store = &context->session()->system().settings();
    out->explicit_store = true;
    out->level = SettingContext::Level::kGlobal;
  } else if (cmd.HasNoun(Noun::kBreakpoint)) {
    out->store = cmd.breakpoint() ? &cmd.breakpoint()->settings() : nullptr;
    out->explicit_store = true;
    out->level = SettingContext::Level::kBreakpoint;
  } else if (cmd.HasNoun(Noun::kFilter)) {
    out->store = cmd.filter() ? &cmd.filter()->settings() : nullptr;
    out->explicit_store = true;
    out->level = SettingContext::Level::kFilter;
  }

  // When no name is specified, there's no implicit setting store to look up.
  if (out->name.empty())
    return Err();

  if (out->store) {
    // Found an explicitly requested setting store.
    if (cmd.verb() == Verb::kSet) {
      // Use the generic definition from the schama (if any).
      if (const SettingSchema::Record* record = out->store->schema()->GetSetting(out->name))
        out->value = record->default_value;
    } else if (cmd.verb() == Verb::kGet) {
      // Use the specific value from the store.
      out->value = out->store->GetValue(out->name);
    }
    return Err();
  }

  // Didn't found an explicit specified store, so lookup in the current context. Since the
  // settings can be duplicated on different levels, we need to search in the order that makes
  // sense for the command.
  out->explicit_store = false;

  // This array encodes the order we search from the most global to most specific store. This is
  // not the same as the SettingStore fallback because "set" searches from global->specific ("get"
  // does the reverse).
  using CheckFunction =
      bool (*)(ConsoleContext*, const Command&, const std::string&, SettingContext*);
  const CheckFunction kGlobalToSpecific[] = {
      &CheckGlobal,
      &CheckTarget,
      &CheckThread,
  };

  if (cmd.verb() == Verb::kSet) {
    // When setting, choose the most global context the setting can apply to.
    for (const auto cur : kGlobalToSpecific) {
      if (cur(context, cmd, out->name, out)) {
        // Just get the default value so the type is set properly.
        out->value = out->store->schema()->GetSetting(out->name)->default_value;
        return Err();
      }
    }
  } else if (cmd.verb() == Verb::kGet) {
    // When getting, choose the most specific context the setting can apply to.
    for (const auto cur : Reversed(kGlobalToSpecific)) {
      if (cur(context, cmd, out->name, out)) {
        // Getting additionally requires that the setting be non-null. We want to find the first
        // one that might apply.
        out->value = out->store->GetValue(out->name);
        if (!out->value.is_null())
          return Err();
      }
    }
  }

  return Err("Could not find setting \"%s\".", out->name.data());
}

// get ---------------------------------------------------------------------------------------------

const char kGetShortHelp[] = "get: Prints setting values.";
const char kGetHelp[] =
    R"([ <object> ] get [ --value-only ] [ <setting-name> ]

  Prints setting values.

  Settings are hierarchical for processes and threads. This means that
  thread settings will inherit from the process if they don't exist on
  the thread, and process settings will inherit from the global settings
  if they don't exist on the process.

get

    By itself, "get" will show the global settings and the ones for the
    current thread and process.

    Example:
      get

get <setting-name>

    Prints the value of the named setting. It will search the current
    thread, followed by the current process, and then global settings.

    Examples:
      get build-dirs
      get show-stdout

<object> get

    Prints all settings from a specific object.

    Examples:
      process 1 thread 1 get
      thread get              // Uses the current thread.
      filter 2 get
      global get              // Explicitly requests only global values
                              // (processes and threads may override).

<object> get <setting-name>

    Prints a named setting from a specific object.

    Examples:
      filter 2 get pattern
      filter get pattern     // Uses the current filter.

Options

  --value-only
      Displays only the value of the setting without any help text or
      formatting.
)";

// Outputs the general settings in the following order: System -> Target -> Thread
Err CompleteSettingsToOutput(const Command& cmd, ConsoleContext* context, OutputBuffer* out) {
  out->Append(OutputBuffer(Syntax::kHeading, "Global\n"));
  out->Append(FormatSettingStore(context, context->session()->system().settings()));
  out->Append("\n");

  if (Target* target = cmd.target(); target && !target->settings().schema()->empty()) {
    auto title = fxl::StringPrintf("Process %d\n", context->IdForTarget(target));
    out->Append(OutputBuffer(Syntax::kHeading, std::move(title)));
    out->Append(FormatSettingStore(context, target->settings()));
    out->Append("\n");
  }

  if (Thread* thread = cmd.thread(); thread && !thread->settings().schema()->empty()) {
    auto title = fxl::StringPrintf("Thread %d\n", context->IdForThread(thread));
    out->Append(OutputBuffer(Syntax::kHeading, std::move(title)));
    out->Append(FormatSettingStore(context, thread->settings()));
    out->Append("\n");
  }

  return Err();
}

Err DoGet(ConsoleContext* console_context, const Command& cmd) {
  std::string input_name;
  if (!cmd.args().empty()) {
    if (cmd.args().size() > 1)
      return Err("Expected only one setting name");
    input_name = cmd.args()[0];
  }

  Err err;
  SettingContext setting_context;
  if (err = GetSettingContext(console_context, cmd, input_name, &setting_context); err.has_error())
    return err;
  // Use setting_context.name from here on down instead of input_name because it's canonicalized.

  OutputBuffer out;
  if (!setting_context.name.empty()) {
    // Getting one setting.
    if (setting_context.value.is_null()) {
      err = Err("Could not find setting %s", setting_context.name.c_str());
    } else if (cmd.HasSwitch(kValueOnlySwitch)) {
      out = FormatSettingValue(console_context, setting_context.value);
    } else {
      const SettingSchema::Record* record =
          setting_context.store->schema()->GetSetting(setting_context.name);
      FX_DCHECK(record);  // Should always succeed if GetSettingContext did.
      out = FormatSetting(console_context, setting_context.name, record->description,
                          setting_context.value);
    }
  } else if (setting_context.explicit_store) {
    // Getting all settings on one object. The object may not be valid (e.g. "thread get" when
    // there's no current thread).
    if (setting_context.store) {
      out.Append(FormatSettingStore(console_context, *setting_context.store));
      out.Append("\n");
    } else {
      err = Err("No current object of this type.");
    }
  } else {
    // Implcitly getting all settings, show the general global/process/thread ones.
    err = CompleteSettingsToOutput(cmd, console_context, &out);
  }

  if (err.has_error())
    return err;
  Console::get()->Output(out);
  return Err();
}

// set ---------------------------------------------------------------------------------------------

const char kSetShortHelp[] = "set: Set a setting value.";
const char kSetHelp[] =
    R"([ <object> ] set <setting-name> [ <modification-type> ] <value>*

  Sets the value of a setting.

  See which settings are available, their names and current values with
  the "get" command (see "help get").

  As a special-case, the syntax "set <setting-name> =" (with no value) will
  clear the setting back to its default value. This can also be used for thread-
  or process-specific settings to case a fallback to the global value.

Arguments

  <object>
      The object that the setting is on. If unspecified, it will search
      the current thread, process, and then the global settings for a
      match to set.

  <setting_name>
      The setting that will modified. Case-insensitive.

  <modification-type>
      Operator that indicates how to mutate a list. For non-lists only = (the
      default) is supported:

      =   Replace the current contents (the default).
      +=  Append the given value to the list.
      -=  Search for the given value and remove it.

  <value>
      The value(s) to set, add, or remove. Multiple values for list settings
      are whitespace separated. You can "quote" strings to include literal
      spaces, and backslash-escape literal quotes.

Setting Types

  Each setting has a particular type.

  bool
      "0", "false" -> false
      "1", "true"  -> true

  integer
      Any string convertible to integer.

  string
      Strings can be "quoted" to include whitespace. Otherwise whitespace is
      used as a delimiter.

  list
      A list of one or more string separated by whitespace. Strings can be
      "quoted" to include literal whitespace.

Examples

  [zxdb] set show-stdout true
  Set global show-stdout = true

  [zxdb] pr 3 set vector-format double
  Set process 3 vector-format = double

  [zxdb] get build-dirs
    • /home/me/build
    • /home/me/other/out

  [zxdb] set build-dirs += /tmp/build
  Set global build-dirs =
    • /home/me/build
    • /home/me/other/out
    • /tmp/build

  [zxdb] set build-dirs = /other/build/location /other/build2
  Set global build-dirs build-dirs =
    • /other/build/location
    • /other/build2

  [zxdb] set build-dirs =
  Set global build-dirs = <empty>
)";

Err SetBool(SettingStore* store, const std::string& setting_name, const std::string& value) {
  std::optional<bool> bool_val = StringToBool(value);
  if (!bool_val)
    return Err("%s expects a boolean. See \"help set\" for valid values.", setting_name.data());

  store->SetBool(setting_name, *bool_val);
  return Err();
}

Err SetInt(SettingStore* store, const std::string& setting_name, const std::string& value) {
  int out;
  Err err = StringToInt(value, &out);
  if (err.has_error()) {
    return Err("%s expects a valid int: %s", setting_name.data(), err.msg().data());
  }

  return store->SetInt(setting_name, out);
}

Err SetList(const SettingContext& setting_context, const std::vector<std::string>& values,
            SettingStore* store) {
  if (setting_context.op == ParsedSetCommand::kAssign)
    return store->SetList(setting_context.name, values);

  if (setting_context.op == ParsedSetCommand::kAppend) {
    auto list = store->GetList(setting_context.name);
    list.insert(list.end(), values.begin(), values.end());
    return store->SetList(setting_context.name, list);
  }

  if (setting_context.op == ParsedSetCommand::kRemove) {
    // Search for the elements to remove.
    auto list = store->GetList(setting_context.name);

    for (const std::string& value : values) {
      auto first_to_remove = std::remove(list.begin(), list.end(), value);
      if (first_to_remove == list.end()) {
        // Item not found.
        return Err("Could not find \"" + value + "\" to remove from setting list.");
      }
      list.erase(first_to_remove, list.end());
    }
    return store->SetList(setting_context.name, list);
  }

  FX_NOTREACHED();
  return Err();
}

Err SetExecutionScope(ConsoleContext* console_context, const SettingContext& setting_context,
                      const std::string& scope_str, SettingStore* store) {
  ErrOr<ExecutionScope> scope_or = ParseExecutionScope(console_context, scope_str);
  if (scope_or.has_error())
    return scope_or.err();

  return store->SetExecutionScope(setting_context.name, scope_or.value());
}

Err SetInputLocations(const Frame* optional_frame, const SettingContext& setting_context,
                      const std::string& input, SettingStore* store) {
  std::vector<InputLocation> locs;
  if (Err err = ParseLocalInputLocation(optional_frame, input, &locs); err.has_error())
    return err;

  return store->SetInputLocations(setting_context.name, std::move(locs));
}

// Will run the sets against the correct SettingStore:
// |setting_context| represents the required context needed to reason about the command.
// for user feedback.
// |out| is the resultant setting, which is used for user feedback.
Err SetSetting(ConsoleContext* console_context, const Frame* optional_frame,
               const SettingContext& setting_context, const std::vector<std::string>& values,
               SettingStore* store, SettingValue* out) {
  Err err;
  if (setting_context.op != ParsedSetCommand::kAssign && !setting_context.value.is_list())
    return Err("Appending/removing only works for list options.");

  if (values.empty()) {
    if (err = store->ClearValue(setting_context.name); err.has_error())
      return err;

    // When clearing, report the new value is the default reported by the store.
    *out = store->GetValue(setting_context.name);
    return Err();
  }

  switch (setting_context.value.type()) {
    case SettingType::kBoolean:
      err = SetBool(store, setting_context.name, values[0]);
      break;
    case SettingType::kInteger:
      err = SetInt(store, setting_context.name, values[0]);
      break;
    case SettingType::kString:
      err = store->SetString(setting_context.name, values[0]);
      break;
    case SettingType::kList:
      err = SetList(setting_context, values, store);
      break;
    case SettingType::kExecutionScope:
      err = SetExecutionScope(console_context, setting_context, values[0], store);
      break;
    case SettingType::kInputLocations:
      err = SetInputLocations(optional_frame, setting_context, values[0], store);
      break;
    case SettingType::kNull:
      return Err("Could not find setting %s.", setting_context.name.c_str());
  }

  if (!err.ok())
    return err;

  *out = store->GetValue(setting_context.name);
  return Err();
}

OutputBuffer FormatSetFeedback(ConsoleContext* console_context,
                               const SettingContext& setting_context,
                               const std::string& setting_name, const Command& cmd,
                               const SettingValue& value) {
  OutputBuffer out;

  std::string message;
  switch (setting_context.level) {
    case SettingContext::Level::kGlobal:
      out.Append("Set global");
      break;
    case SettingContext::Level::kTarget:
      out.Append("Set process ");
      out.Append(Syntax::kSpecial, std::to_string(console_context->IdForTarget(cmd.target())));
      break;
    case SettingContext::Level::kThread:
      out.Append("Set process ");
      out.Append(Syntax::kSpecial, std::to_string(console_context->IdForTarget(cmd.target())));
      out.Append(" thread ");
      out.Append(Syntax::kSpecial, std::to_string(console_context->IdForThread(cmd.thread())));
      break;
    case SettingContext::Level::kBreakpoint:
      out.Append("Set breakpoint ");
      out.Append(Syntax::kSpecial,
                 std::to_string(console_context->IdForBreakpoint(cmd.breakpoint())));
      break;
    case SettingContext::Level::kFilter:
      out.Append("Set filter ");
      out.Append(Syntax::kSpecial, std::to_string(console_context->IdForFilter(cmd.filter())));
      break;
    default:
      FX_NOTREACHED() << "Should not receive a default setting.";
  }

  out.Append(" ");
  out.Append(Syntax::kVariable, setting_name);
  out.Append(" = ");

  if (value.is_list() && !value.get_list().empty())
    out.Append("\n");  // Put list items on their own lines.
  out.Append(FormatSettingShort(console_context, setting_name, value, 2));
  return out;
}

Err DoSet(ConsoleContext* console_context, const Command& cmd) {
  // The command parser will provide everything as one argument.
  if (cmd.args().size() != 1)
    return Err("Wrong amount of Arguments. See \"help set\".");

  ErrOr<ParsedSetCommand> parsed = ParseSetCommand(cmd.args()[0]);
  if (parsed.has_error())
    return parsed.err();

  // See where this setting would be stored.
  SettingContext setting_context;
  Err err = GetSettingContext(console_context, cmd, parsed.value().name, &setting_context);
  if (err.has_error())
    return err;
  setting_context.op = parsed.value().op;

  // Validate that the operations makes sense.
  if (parsed.value().op != ParsedSetCommand::kAssign && !setting_context.value.is_list())
    return Err("List modification (+=, -=) used on a non-list option.");

  if (parsed.value().values.size() > 1u && !setting_context.value.is_list()) {
    // When the value is a non-list, assume input with spaces is a single literal. This allows
    // input like:
    //    bp set scope process 1
    // without quoting "process 1" which is much more intuitive. The potentially surprising side
    // effect of this rule is that if two things are quoted (triggering this condition), the quotes
    // will be literally included in the value, while if only one thing is quoted, the quotes will
    // br trimmed. But this edge case is not worth adding extra complexity here.
    parsed.value().values.clear();
    parsed.value().values.push_back(parsed.value().raw_value);
  }

  SettingValue out_value;  // Used for showing the new value.
  err = SetSetting(console_context, cmd.frame(), setting_context, parsed.value().values,
                   setting_context.store, &out_value);
  if (!err.ok())
    return err;

  // Be sure to use the canonicalized name in the setting_context for the output.
  Console::get()->Output(
      FormatSetFeedback(console_context, setting_context, setting_context.name, cmd, out_value));
  return Err();
}

// Equivalend to isalpha with no C local complexity.
bool IsSettingNameAlpha(const char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); }

// Setting names are only letters and hyphens.
//
// The "name" is annoying to parse because it can't end in a "-" and we have to differentiate that
// from a "name-=..." command which requires lookahead. As a result, this takes the full string
// and the index of the character to check.
bool IsSettingNameChar(const std::string& input, size_t i) {
  if (IsSettingNameAlpha(input[i]))
    return true;  // Normal letter.

  if (input[i] == '-') {
    // Disambiguate internal hyphens from "-=".
    if (i + 1 < input.size() && IsSettingNameAlpha(input[i + 1]))
      return true;  // More name to come.
  }

  return false;
}

void CompleteSet(const Command& cmd, const std::string& prefix,
                 std::vector<std::string>* completions) {
  // Find the end of the setting name. The argument is a whole expression as one string, so if we're
  // past the setting name we're past the part we know how to complete.
  size_t cur;
  for (cur = 0; cur < prefix.size() && IsSettingNameChar(prefix, cur); ++cur)
    ;

  if (cur == prefix.size()) {
    for (const auto& [name, _] : System::GetSchema()->settings()) {
      if (!name.compare(0, prefix.size(), prefix)) {
        completions->push_back(name);
      }
    }

    for (const auto& [name, _] : Target::GetSchema()->settings()) {
      if (!name.compare(0, prefix.size(), prefix)) {
        completions->push_back(name);
      }
    }

    for (const auto& [name, _] : Thread::GetSchema()->settings()) {
      if (!name.compare(0, prefix.size(), prefix)) {
        completions->push_back(name);
      }
    }
  }

  // TODO: We need to refactor parsing a bit if we want to complete options.
}

}  // namespace

// Grammar:
//   command := <name> [ <whitespace> ] [ <operator> <whitespace> ] [ <value> * ]
//   name := ('A' - 'Z') | ('a' - 'z') | '-'  // See IsSettingNameChar() for qualifications.
//   operator := "=" | '+=' | '-='
//
// A "value" is a possibly quoted string parsed as a command token. The whole thing can't be parsed
// as a command because we want to handle "name value" as well as "name = value" and "name=value".
ErrOr<ParsedSetCommand> ParseSetCommand(const std::string& input) {
  ParsedSetCommand result;
  size_t cur = 0;

  // Name.
  while (cur < input.size() && IsSettingNameChar(input, cur)) {
    result.name.push_back(input[cur]);
    ++cur;
  }
  if (result.name.empty())
    return Err("Expected a setting name to set.");

  // Require whitespace or an operator after the name to prevent "name$" from being valid.
  bool has_name_terminator = false;

  // Whitespace.
  while (cur < input.size() && isspace(input[cur])) {
    has_name_terminator = true;
    ++cur;
  }

  // Special-case the error message for no value to be more helpful. To clear the value we require
  // "=" so the command is more explicit ("set foo" may be typed by somebody who doesn't know what
  // they're doing).
  if (cur == input.size())
    return Err("Expecting a value to set. Use \"set setting-name setting-value\".");

  // Optional operator.
  if (cur < input.size() && input[cur] == '=') {
    has_name_terminator = true;
    result.op = ParsedSetCommand::kAssign;
    ++cur;
  } else if (cur < input.size() - 1 && input[cur] == '+' && input[cur + 1] == '=') {
    has_name_terminator = true;
    result.op = ParsedSetCommand::kAppend;
    cur += 2;
  } else if (cur < input.size() - 1 && input[cur] == '-' && input[cur + 1] == '=') {
    has_name_terminator = true;
    result.op = ParsedSetCommand::kRemove;
    cur += 2;
  }

  // Check for the name terminator.
  if (!has_name_terminator)
    return Err("Invalid setting name.");

  // Whitespace.
  while (cur < input.size() && isspace(input[cur]))
    ++cur;

  // Save the original raw value (trimming whitespace from the right).
  result.raw_value = input.substr(cur);
  while (!result.raw_value.empty() && isspace(result.raw_value.back()))
    result.raw_value.resize(result.raw_value.size() - 1);

  // Value(s) parsed as a command token. This handles the various types of escaping and quoting
  // supported by the interactive command line.
  //
  // The value can be omitted for sets which clears the value to the default.
  std::vector<CommandToken> value_tokens;
  if (Err err = TokenizeCommand(input.substr(cur), &value_tokens); err.has_error())
    return err;
  if (result.op != ParsedSetCommand::kAssign && value_tokens.empty())
    return Err("Expected a value to add/remove.");

  for (const auto& token : value_tokens)
    result.values.push_back(std::move(token.str));
  return result;
}

ErrOr<ExecutionScope> ParseExecutionScope(ConsoleContext* console_context,
                                          const std::string& input) {
  // Use the command parser to get the scope.
  Command parsed;
  if (Err err = ParseCommand(input, &parsed); err.has_error())
    return err;

  const char kScopeHelp[] =
      "Scope not valid, expecting \"global\", \"process\", or \"thread\" only.";

  // We accept the "global", "process", and "thread" nouns, and no verbs or switches.
  if (parsed.verb() != Verb::kNone)
    return Err(kScopeHelp);
  if (parsed.ValidateNouns({Noun::kGlobal, Noun::kProcess, Noun::kThread}).has_error())
    return Err(kScopeHelp);
  if (!parsed.args().empty())
    return Err(kScopeHelp);

  // Convert the nouns to objects.
  if (Err err = console_context->FillOutCommand(&parsed); err.has_error())
    return err;

  // Valid, convert to scope based on what nouns were specified. The thread or process could have
  // failed to resolve to objects if there is no current one.
  if (parsed.HasNoun(Noun::kThread)) {
    if (!parsed.thread())
      return Err("There is no current thread to use for the scope.");
    return ExecutionScope(parsed.thread());
  }
  if (parsed.HasNoun(Noun::kProcess)) {
    if (!parsed.target())
      return Err("There is no current process to use for the scope.");
    return ExecutionScope(parsed.target());
  }
  return ExecutionScope();
}

void AppendSettingsVerbs(std::map<Verb, VerbRecord>* verbs) {
  VerbRecord get(&DoGet, {"get"}, kGetShortHelp, kGetHelp, CommandGroup::kGeneral);
  get.switches.emplace_back(kValueOnlySwitch, false, "value-only");
  (*verbs)[Verb::kGet] = std::move(get);

  VerbRecord set(&DoSet, &CompleteSet, {"set"}, kSetShortHelp, kSetHelp, CommandGroup::kGeneral);
  set.param_type = VerbRecord::kOneParam;
  (*verbs)[Verb::kSet] = std::move(set);
}

}  // namespace zxdb
