// Copyright 2018 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/command_utils.h"

#include <ctype.h>
#include <inttypes.h>
#include <lib/syslog/cpp/macros.h>
#include <stdio.h>

#include <limits>

#include "src/developer/debug/zxdb/client/breakpoint.h"
#include "src/developer/debug/zxdb/client/breakpoint_location.h"
#include "src/developer/debug/zxdb/client/client_eval_context_impl.h"
#include "src/developer/debug/zxdb/client/filter.h"
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/job.h"
#include "src/developer/debug/zxdb/client/process.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/source_file_provider_impl.h"
#include "src/developer/debug/zxdb/client/target.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/common/string_util.h"
#include "src/developer/debug/zxdb/console/command.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_context.h"
#include "src/developer/debug/zxdb/console/format_job.h"
#include "src/developer/debug/zxdb/console/format_location.h"
#include "src/developer/debug/zxdb/console/format_name.h"
#include "src/developer/debug/zxdb/console/format_node_console.h"
#include "src/developer/debug/zxdb/console/format_target.h"
#include "src/developer/debug/zxdb/console/input_location_parser.h"
#include "src/developer/debug/zxdb/console/output_buffer.h"
#include "src/developer/debug/zxdb/console/string_util.h"
#include "src/developer/debug/zxdb/expr/eval_context_impl.h"
#include "src/developer/debug/zxdb/expr/expr.h"
#include "src/developer/debug/zxdb/expr/expr_parser.h"
#include "src/developer/debug/zxdb/expr/expr_value.h"
#include "src/developer/debug/zxdb/expr/format.h"
#include "src/developer/debug/zxdb/expr/number_parser.h"
#include "src/developer/debug/zxdb/expr/return_value.h"
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/elf_symbol.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/identifier.h"
#include "src/developer/debug/zxdb/symbols/location.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"
#include "src/developer/debug/zxdb/symbols/process_symbols.h"
#include "src/developer/debug/zxdb/symbols/symbol_utils.h"
#include "src/developer/debug/zxdb/symbols/target_symbols.h"
#include "src/developer/debug/zxdb/symbols/variable.h"
#include "src/lib/fxl/strings/string_printf.h"
#include "src/lib/fxl/strings/trim.h"

namespace zxdb {

Err AssertRunningTarget(ConsoleContext* context, const char* command_name, Target* target) {
  Target::State state = target->GetState();
  if (state == Target::State::kRunning)
    return Err();
  return Err(ErrType::kInput,
             fxl::StringPrintf("%s requires a running process but process %d is %s.", command_name,
                               context->IdForTarget(target), TargetStateToString(state)));
}

Err AssertStoppedThreadCommand(ConsoleContext* context, const Command& cmd, bool validate_nouns,
                               const char* command_name) {
  Err err;
  if (validate_nouns) {
    err = cmd.ValidateNouns({Noun::kProcess, Noun::kThread});
    if (err.has_error())
      return err;
  }

  if (!cmd.thread()) {
    return Err("\"%s\" requires a thread but there is no current thread.", command_name);
  }
  if (cmd.thread()->GetState() != debug_ipc::ThreadRecord::State::kBlocked &&
      cmd.thread()->GetState() != debug_ipc::ThreadRecord::State::kCoreDump &&
      cmd.thread()->GetState() != debug_ipc::ThreadRecord::State::kSuspended) {
    return Err(
        "\"%s\" requires a suspended thread but thread %d is %s.\n"
        "To view and sync thread state with the remote system, type "
        "\"thread\".",
        command_name, context->IdForThread(cmd.thread()),
        ThreadStateToString(cmd.thread()->GetState(), cmd.thread()->GetBlockedReason()).c_str());
  }
  return Err();
}

Err AssertStoppedThreadWithFrameCommand(ConsoleContext* context, const Command& cmd,
                                        const char* command_name) {
  // Does most validation except noun checking.
  Err err = AssertStoppedThreadCommand(context, cmd, false, command_name);
  if (err.has_error())
    return err;

  if (!cmd.frame()) {
    return Err(
        "\"%s\" requires a stack frame but none is available.\n"
        "You may need to \"pause\" the thread or sync the frames with \"frame\".",
        command_name);
  }

  return cmd.ValidateNouns({Noun::kProcess, Noun::kThread, Noun::kFrame});
}

size_t CheckHexPrefix(const std::string& s) {
  if (s.size() >= 2u && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
    return 2u;
  return 0u;
}

Err StringToInt(const std::string& s, int* out) {
  int64_t value64;
  Err err = StringToInt64(s, &value64);
  if (err.has_error())
    return err;

  // Range check it can be stored in an int.
  if (value64 < static_cast<int64_t>(std::numeric_limits<int>::min()) ||
      value64 > static_cast<int64_t>(std::numeric_limits<int>::max()))
    return Err("This value is too large for an integer.");

  *out = static_cast<int>(value64);
  return Err();
}

Err StringToInt64(const std::string& s, int64_t* out) {
  *out = 0;

  // StringToNumber expects pre-trimmed input.
  std::string trimmed(fxl::TrimString(s, " "));

  ErrOrValue number_value = StringToNumber(ExprLanguage::kC, trimmed);
  if (number_value.has_error())
    return number_value.err();

  // Be careful to read the number out in its original sign-edness.
  if (number_value.value().GetBaseType() == BaseType::kBaseTypeUnsigned) {
    uint64_t u64;
    Err err = number_value.value().PromoteTo64(&u64);
    if (err.has_error())
      return err;

    // Range-check that the unsigned value can be put in a signed.
    if (u64 > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()))
      return Err("This value is too large.");
    *out = static_cast<int64_t>(u64);
    return Err();
  }

  // Expect everything else to be a signed number.
  if (number_value.value().GetBaseType() != BaseType::kBaseTypeSigned)
    return Err("This value is not the correct type.");
  return number_value.value().PromoteTo64(out);
}

Err StringToUint32(const std::string& s, uint32_t* out) {
  // Re-uses StringToUint64's and just size-checks the output.
  uint64_t value64;
  Err err = StringToUint64(s, &value64);
  if (err.has_error())
    return err;

  if (value64 > static_cast<uint64_t>(std::numeric_limits<uint32_t>::max())) {
    return Err("Expected 32-bit unsigned value, but %s is too large.", s.c_str());
  }
  *out = static_cast<uint32_t>(value64);
  return Err();
}

Err StringToUint64(const std::string& s, uint64_t* out) {
  *out = 0;

  // StringToNumber expects pre-trimmed input.
  std::string trimmed(fxl::TrimString(s, " "));

  ErrOrValue number_value = StringToNumber(ExprLanguage::kC, trimmed);
  if (number_value.has_error())
    return number_value.err();

  // Be careful to read the number out in its original sign-edness.
  if (number_value.value().GetBaseType() == BaseType::kBaseTypeSigned) {
    int64_t s64;
    Err err = number_value.value().PromoteTo64(&s64);
    if (err.has_error())
      return err;

    // Range-check that the signed value can be put in an unsigned.
    if (s64 < 0)
      return Err("This value can not be negative.");
    *out = static_cast<uint64_t>(s64);
    return Err();
  }

  // Expect everything else to be an unsigned number.
  if (number_value.value().GetBaseType() != BaseType::kBaseTypeUnsigned)
    return Err("This value is not the correct type.");
  return number_value.value().PromoteTo64(out);
}

Err ReadUint64Arg(const Command& cmd, size_t arg_index, const char* param_desc, uint64_t* out) {
  if (cmd.args().size() <= arg_index) {
    return Err(ErrType::kInput,
               fxl::StringPrintf("Not enough arguments when reading the %s.", param_desc));
  }
  Err result = StringToUint64(cmd.args()[arg_index], out);
  if (result.has_error()) {
    return Err(ErrType::kInput, fxl::StringPrintf("Invalid number \"%s\" when reading the %s.",
                                                  cmd.args()[arg_index].c_str(), param_desc));
  }
  return Err();
}

std::string ThreadStateToString(debug_ipc::ThreadRecord::State state,
                                debug_ipc::ThreadRecord::BlockedReason blocked_reason) {
  // Blocked can have many cases, so we handle it separately.
  if (state != debug_ipc::ThreadRecord::State::kBlocked)
    return debug_ipc::ThreadRecord::StateToString(state);

  FX_DCHECK(blocked_reason != debug_ipc::ThreadRecord::BlockedReason::kNotBlocked)
      << "A blocked thread has to have a valid reason.";
  return fxl::StringPrintf("Blocked (%s)",
                           debug_ipc::ThreadRecord::BlockedReasonToString(blocked_reason));
}

std::string ExecutionScopeToString(const ConsoleContext* context, const ExecutionScope& scope) {
  switch (scope.type()) {
    case ExecutionScope::kSystem:
      return "global";
    case ExecutionScope::kTarget:
      if (scope.target())
        return fxl::StringPrintf("pr %d", context->IdForTarget(scope.target()));
      return "<Deleted process>";
    case ExecutionScope::kThread:
      if (scope.thread()) {
        return fxl::StringPrintf("pr %d t %d", context->IdForTarget(scope.target()),
                                 context->IdForThread(scope.thread()));
      }
      return "<Deleted thread>";
  }
  FX_NOTREACHED();
  return std::string();
}

ExecutionScope ExecutionScopeForCommand(const Command& cmd) {
  if (cmd.HasNoun(Noun::kThread))
    return ExecutionScope(cmd.thread());  // Thread context given explicitly.
  if (cmd.HasNoun(Noun::kProcess))
    return ExecutionScope(cmd.target());  // Target context given explicitly.

  return ExecutionScope();  // Everything else becomes global scope.
}

Err ResolveBreakpointsForModification(const Command& cmd, const char* command_name,
                                      std::vector<Breakpoint*>* output) {
  output->clear();

  if (cmd.args().size() > 1) {
    return Err(ErrType::kInput,
               "Expecting zero or one arg for the location.\n"
               "Formats: <function>, <file>:<line#>, <line#>, or 0x<address>");
  }

  if (cmd.args().size() == 1) {
    // "bp <index> clear <location>" is pointless.
    Err err = cmd.ValidateNouns({});
    if (err.has_error())
      return err;

    // No need to resolve the location here because pending breakpoints only have input_locations.
    // As a result, if a user has breakpoints on both main and $main, "clear main" will only clear
    // the first breakpoint.
    std::vector<InputLocation> input_locations;
    if (Err err = ParseLocalInputLocation(cmd.frame(), cmd.args()[0], &input_locations);
        err.has_error())
      return err;

    ConsoleContext* context = &Console::get()->context();
    std::vector<Breakpoint*> breakpoints = context->session()->system().GetBreakpoints();

    for (Breakpoint* breakpoint : breakpoints) {
      // We compare the input_locations vector directly, in hopes that the same input will
      // resolve to the same order.
      if (input_locations == breakpoint->GetSettings().locations) {
        output->push_back(breakpoint);
      }
    }

    if (output->size() == 0) {
      auto msg = fxl::StringPrintf("\"%s\" matches zero breakpoints.", cmd.args()[0].c_str());
      if (cmd.args()[0].size() && isdigit(cmd.args()[0][0]))
        msg += fxl::StringPrintf(" Maybe you want to use \"bp %s %s\"?", cmd.args()[0].c_str(),
                                 command_name);
      return Err(msg);
    }
    return Err();
  }

  // When cmd.args().size() == 0, use the command's breakpoint context.
  Err err = cmd.ValidateNouns({Noun::kBreakpoint});
  if (err.has_error())
    return err;

  if (!cmd.breakpoint()) {
    return Err(
        fxl::StringPrintf("There is no active breakpoint and no breakpoint or location was given.\n"
                          "Use \"bp <index> %s\" or \"%s <location>\" to specify one.\n",
                          command_name, command_name));
  }

  output->push_back(cmd.breakpoint());
  return Err();
}

OutputBuffer FormatThread(const ConsoleContext* context, const Thread* thread) {
  OutputBuffer out("Thread ");
  out.Append(Syntax::kSpecial, std::to_string(context->IdForThread(thread)));

  out.Append(Syntax::kVariable, " state");
  out.Append("=" + FormatConsoleString(
                       ThreadStateToString(thread->GetState(), thread->GetBlockedReason())));

  out.Append(Syntax::kVariable, " koid");
  out.Append("=" + std::to_string(thread->GetKoid()));

  out.Append(Syntax::kVariable, " name");
  out.Append("=" + FormatConsoleString(thread->GetName()));

  return out;
}

OutputBuffer FormatBreakpoint(const ConsoleContext* context, const Breakpoint* breakpoint,
                              bool show_context) {
  BreakpointSettings settings = breakpoint->GetSettings();

  OutputBuffer result("Breakpoint ");
  result.Append(Syntax::kSpecial, std::to_string(context->IdForBreakpoint(breakpoint)) + " ");

  // Most breakpoints are simple global software breakpoints. To keep things easier to follow,
  // only show values that aren't the default.
  if (settings.scope.type() != ExecutionScope::kSystem) {
    result.Append(Syntax::kVariable, ClientSettings::Breakpoint::kScope);
    result.Append(std::string("=\"") + ExecutionScopeToString(context, settings.scope) + "\" ");
  }

  if (settings.stop_mode != BreakpointSettings::StopMode::kAll) {
    result.Append(Syntax::kVariable, ClientSettings::Breakpoint::kStopMode);
    result.Append(std::string("=") + BreakpointSettings::StopModeToString(settings.stop_mode) +
                  " ");
  }

  if (!settings.enabled) {
    result.Append(Syntax::kVariable, ClientSettings::Breakpoint::kEnabled);
    result.Append("=");
    if (settings.enabled) {
      result.Append("true");
    } else {
      // Highlight disabled breakpoints since that's an unusual condition.
      result.Append(Syntax::kError, "false");
    }
    result.Append(" ");
  }

  // Include type only for non-software (the normal ones) breakpoints.
  if (settings.type != BreakpointSettings::Type::kSoftware) {
    result.Append(Syntax::kVariable, ClientSettings::Breakpoint::kType);
    result.Append(std::string("=") + BreakpointSettings::TypeToString(settings.type) + " ");
  }

  if (BreakpointSettings::TypeHasSize(settings.type)) {
    result.Append(Syntax::kVariable, ClientSettings::Breakpoint::kSize);
    result.Append("=" + std::to_string(settings.byte_size) + " ");
  }

  if (settings.one_shot) {
    result.Append(Syntax::kVariable, ClientSettings::Breakpoint::kOneShot);
    result.Append(std::string("=") + BoolToString(settings.one_shot) + " ");
  }

  bool show_location_details = !settings.locations.empty() && show_context;

  size_t matched_locs = breakpoint->GetLocations().size();
  if (matched_locs == 0) {
    // When more details are being shown below, don't duplicate the "pending" warning.
    if (!show_location_details)
      result.Append(Syntax::kWarning, "pending ");
    result.Append("@ ");
  } else if (matched_locs == 1) {
    result.Append("@ ");
  } else {
    result.Append(fxl::StringPrintf("(%zu addrs) @ ", matched_locs));
  }
  result.Append(FormatInputLocations(settings.locations));
  result.Append("\n");

  if (show_location_details) {
    // Append the source code location.
    //
    // There is a question of how to show the breakpoint enabled state. The breakpoint has a main
    // enabled bit and each location (it can apply to more than one address -- think templates and
    // inlined functions) within that breakpoint has its own. But each location normally resolves to
    // the same source code location so we can't practically show the individual location's enabled
    // state separately.
    //
    // For simplicity, just base it on the main enabled bit. Most people won't use location-specific
    // enabling anyway.
    //
    // Ignore errors from printing the source, it doesn't matter that much. Since breakpoints are in
    // the global scope we have to use the global settings for the build dir. We could use the
    // process build dir for process-specific breakpoints but both process-specific breakpoints and
    // process-specific build settings are rare.
    if (auto locs = breakpoint->GetLocations(); !locs.empty()) {
      FormatBreakpointContext(locs[0]->GetLocation(),
                              SourceFileProviderImpl(breakpoint->session()->system().settings()),
                              settings.enabled, &result);
    } else {
      // When the breakpoint resolved to nothing, warn the user, they may have made a typo.
      result.Append(Syntax::kWarning, "Pending");
      result.Append(
          ": No current matches for location. It will be matched against new\n"
          "         processes and shared libraries.\n");
    }
  }
  return result;
}

OutputBuffer FormatInputLocation(const InputLocation& location) {
  switch (location.type) {
    case InputLocation::Type::kNone: {
      return OutputBuffer(Syntax::kComment, "<no location>");
    }
    case InputLocation::Type::kLine: {
      // Don't pass a TargetSymbols to FormatFileLine because we always want the full file name as
      // passed-in by the user (as this is an "input" location object). It is surprising if the
      // debugger deletes some input.
      return OutputBuffer(FormatFileLine(location.line));
    }
    case InputLocation::Type::kName: {
      FormatIdentifierOptions opts;
      opts.show_global_qual = true;  // Imporant to disambiguate for InputLocations.
      opts.bold_last = true;
      return FormatIdentifier(location.name, opts);
    }
    case InputLocation::Type::kAddress: {
      return OutputBuffer(to_hex_string(location.address));
    }
  }
  FX_NOTREACHED();
  return OutputBuffer();
}

OutputBuffer FormatInputLocations(const std::vector<InputLocation>& locations) {
  if (locations.empty())
    return OutputBuffer(Syntax::kComment, "<no location>");

  // Comma-separate if there are multiples.
  bool first_location = true;
  OutputBuffer result;
  for (const auto& loc : locations) {
    if (!first_location)
      result.Append(", ");
    else
      first_location = false;
    result.Append(FormatInputLocation(loc));
  }
  return result;
}

fxl::RefPtr<EvalContext> GetEvalContextForCommand(const Command& cmd) {
  if (cmd.frame())
    return cmd.frame()->GetEvalContext();

  std::optional<ExprLanguage> language;
  auto language_setting =
      cmd.target()->session()->system().settings().GetString(ClientSettings::System::kLanguage);
  if (language_setting == ClientSettings::System::kLanguage_Rust) {
    language = ExprLanguage::kRust;
  } else if (language_setting == ClientSettings::System::kLanguage_Cpp) {
    language = ExprLanguage::kC;
  } else {
    FX_DCHECK(language_setting == ClientSettings::System::kLanguage_Auto);
  }

  // Target context only (it may or may not have a process).
  return fxl::MakeRefCounted<ClientEvalContextImpl>(cmd.target(), language);
}

Err EvalCommandExpression(const Command& cmd, const char* verb,
                          const fxl::RefPtr<EvalContext>& eval_context, bool follow_references,
                          bool verbose_errors, EvalCallback cb) {
  if (Err err = cmd.ValidateNouns({Noun::kProcess, Noun::kThread, Noun::kFrame}); err.has_error())
    return err;

  if (cmd.args().size() != 1)
    return Err("Usage: %s <expression>\nSee \"help %s\" for more.", verb, verb);

  EvalExpression(
      cmd.args()[0], std::move(eval_context), follow_references,
      [verbose_errors, cb = std::move(cb), verb = std::string(verb)](ErrOrValue result) mutable {
        if (verbose_errors && result.has_error()) {
          cb(RewriteCommandExpressionError(verb, result.err()));
        } else {
          cb(std::move(result));
        }
      });
  return Err();
}

Err EvalCommandAddressExpression(
    const Command& cmd, const char* verb, const fxl::RefPtr<EvalContext>& eval_context,
    fit::callback<void(const Err& err, uint64_t address, std::optional<uint32_t> size)> cb) {
  return EvalCommandExpression(
      cmd, verb, eval_context, true, true,
      [eval_context, verb = std::string(verb), cb = std::move(cb)](ErrOrValue value) mutable {
        if (value.has_error())
          return cb(value.err(), 0, std::nullopt);

        uint64_t address = 0;
        std::optional<uint32_t> size;

        if (Err err = ValueToAddressAndSize(eval_context, value.value(), &address, &size);
            err.has_error())
          return cb(RewriteCommandExpressionError(verb, err), 0, std::nullopt);
        cb(Err(), address, size);
      });
}

// Errors from the evaluation of expressions of commands oftem don't make sense without context.
Err RewriteCommandExpressionError(const std::string& verb, const Err& err) {
  if (err.type() == ErrType::kOptimizedOut) {
    // The common error messagess "unavailable" and "optimized out" (both sharing kOptimizedOut) are
    // very short because they're often included in long dumps of structures and local variables.
    // But it makes this common class of errors very mysterious here.
    return Err(
        "This variable is %s. Nothing has happened.\n"
        "See \"help expressions\" for more on what this means and what to do.",
        err.msg().c_str());
  }

  // All other errors.
  std::string effective_verb = verb.empty() ? std::string("the command") : verb;
  return Err("Unable to evaluate the expression for " + effective_verb + ". The result was:\n  " +
             err.msg());
}

std::string FormatConsoleString(const std::string& input) {
  // The console parser accepts two forms:
  //  - A C-style string (raw or not) with quotes and C-style escape sequences.
  //  - A whitespace-separated string with no escape character handling.

  if (input.empty())
    return std::string("\"\"");  // Empty strings need quotes.

  // Determine which of the cases is required.
  bool has_space = false;
  bool has_special = false;
  bool has_quote = false;
  for (unsigned char c : input) {
    if (isspace(c)) {
      has_space = true;
    } else if (c < ' ') {
      has_special = true;
    } else if (c == '"') {
      has_quote = true;
    }
    // We assume any high-bit characters are part of UTF-8 sequences. This isn't necessarily the
    // case. We could validate UTF-8 sequences but currently that effort isn't worth it.
  }

  if (!has_space && !has_special && !has_quote)
    return input;

  std::string result;
  if (has_quote && !has_special) {
    // Raw-encode strings with embedded quotes as long as nothing else needs escaping.

    // Make sure there's a unique delimiter in case the string has an embedded )".
    std::string delim;
    while (input.find(")" + delim + "\"") != std::string::npos)
      delim += "*";

    result = "R\"" + delim + "(";
    result += input;
    result += ")" + delim + "\"";
  } else {
    // Normal C string.
    result = "\"";
    for (char c : input)
      AppendCEscapedChar(c, &result);
    result += "\"";
  }
  return result;
}

ErrOr<Target*> GetRunnableTarget(ConsoleContext* context, const Command& cmd) {
  Target::State state = cmd.target()->GetState();
  if (state == Target::State::kNone)
    return cmd.target();  // Current one is usable.

  if (cmd.GetNounIndex(Noun::kProcess) != Command::kNoIndex) {
    // A process was specified explicitly in the command. Since it's not usable, report an error.
    if (state == Target::State::kStarting || state == Target::State::kAttaching) {
      return Err(
          "The specified process is in the process of starting or attaching.\n"
          "Either \"kill\" it or create a \"new\" process context.");
    }
    return Err(
        "The specified process is already running.\n"
        "Either \"kill\" it or create a \"new\" process context.");
  }

  // Create a new target based on the given one.
  Target* new_target = context->session()->system().CreateNewTarget(cmd.target());
  context->SetActiveTarget(new_target);
  return new_target;
}

Err VerifySystemHasRunningProcess(System* system) {
  for (const Target* target : system->GetTargets()) {
    if (target->GetProcess())
      return Err();
  }
  return Err("No processes are running.");
}

void ProcessCommandCallback(fxl::WeakPtr<Target> target, bool display_message_on_success,
                            const Err& err, CommandCallback callback) {
  if (display_message_on_success || err.has_error()) {
    // Display messaging.
    Console* console = Console::get();

    OutputBuffer out;
    if (err.has_error()) {
      out.Append(err);
    } else if (target) {
      out.Append(FormatTarget(&console->context(), target.get()));
    }

    console->Output(out);
  }

  if (callback)
    callback(err);
}

void JobCommandCallback(const char* verb, fxl::WeakPtr<Job> job, bool display_message_on_success,
                        const Err& err, CommandCallback callback) {
  if (!display_message_on_success && !err.has_error())
    return;

  Console* console = Console::get();

  OutputBuffer out;
  if (err.has_error()) {
    if (job) {
      out.Append(
          fxl::StringPrintf("Job %d %s failed.\n", console->context().IdForJob(job.get()), verb));
    }
    out.Append(err);
  } else if (job) {
    out.Append(FormatJob(&console->context(), job.get()));
  }

  console->Output(out);

  if (callback) {
    callback(err);
  }
}

void AsyncPrintReturnValue(const FunctionReturnInfo& info, fit::deferred_callback cb) {
  // This only works for symbolized functions.
  const Function* func = info.symbol.Get()->As<Function>();
  if (!func)
    return;

  const Stack& stack = info.thread->GetStack();
  if (stack.empty())
    return;  // Something is messed up.
  auto eval_context = stack[0]->GetEvalContext();

  GetReturnValue(eval_context, func,
                 [eval_context, func = RefPtrTo(func), cb = std::move(cb)](ErrOrValue val) mutable {
                   if (val.has_error() || !val.value().type())
                     return;  // Error or void.

                   auto out = fxl::MakeRefCounted<AsyncOutputBuffer>();

                   FormatFunctionNameOptions func_name_options;
                   func_name_options.name.elide_templates = true;
                   func_name_options.name.bold_last = true;
                   func_name_options.params = FormatFunctionNameOptions::kNoParams;
                   out->Append(FormatFunctionName(func.get(), func_name_options));
                   out->Append(Syntax::kOperatorBold, " 🡲 ");

                   ConsoleFormatOptions val_options;
                   val_options.verbosity = ConsoleFormatOptions::Verbosity::kMinimal;
                   val_options.wrapping = ConsoleFormatOptions::Wrapping::kSmart;
                   val_options.max_depth = 3;

                   out->Append(FormatValueForConsole(val.value(), val_options, eval_context));

                   out->Complete();
                   if (out->is_complete()) {
                     Console::get()->Output(out->DestructiveFlatten());
                   } else {
                     out->SetCompletionCallback([out = std::move(out), cb = std::move(cb)]() {
                       Console::get()->Output(out->DestructiveFlatten());
                     });
                   }
                 });
}

void ScheduleAsyncPrintReturnValue(const FunctionReturnInfo& info) {
  info.thread->AddPostStopTask(
      [weak_thread = info.thread->GetWeakPtr(), info](fit::deferred_callback cb) {
        // The FunctionReturnInfo has a thread pointer in it and we need to be sure it stays in
        // scope before continuing, even though we don't use the weak pointer directly.
        if (!weak_thread)
          return;
        AsyncPrintReturnValue(info, std::move(cb));
      });
}

}  // namespace zxdb
