//===-- CommandObjectDWIMPrint.cpp ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "CommandObjectDWIMPrint.h"

#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "llvm/ADT/StringRef.h"

#include <regex>

using namespace llvm;
using namespace lldb;
using namespace lldb_private;

CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter)
    : CommandObjectRaw(interpreter, "dwim-print",
                       "Print a variable or expression.",
                       "dwim-print [<variable-name> | <expression>]",
                       eCommandProcessMustBePaused | eCommandTryTargetAPILock |
                           eCommandAllowsDummyTarget) {

  AddSimpleArgumentList(eArgTypeVarName);

  m_option_group.Append(&m_format_options,
                        OptionGroupFormat::OPTION_GROUP_FORMAT |
                            OptionGroupFormat::OPTION_GROUP_GDB_FMT,
                        LLDB_OPT_SET_1);
  StringRef exclude_expr_options[] = {"debug", "top-level"};
  m_option_group.Append(&m_expr_options, exclude_expr_options);
  m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
  m_option_group.Finalize();
}

Options *CommandObjectDWIMPrint::GetOptions() { return &m_option_group; }

void CommandObjectDWIMPrint::DoExecute(StringRef command,
                                       CommandReturnObject &result) {
  m_option_group.NotifyOptionParsingStarting(&m_exe_ctx);
  OptionsWithRaw args{command};
  StringRef expr = args.GetRawPart();

  if (expr.empty()) {
    result.AppendErrorWithFormatv("'{0}' takes a variable or expression",
                                  m_cmd_name);
    return;
  }

  if (args.HasArgs()) {
    if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
                               m_exe_ctx))
      return;
  }

  // If the user has not specified, default to disabling persistent results.
  if (m_expr_options.suppress_persistent_result == eLazyBoolCalculate)
    m_expr_options.suppress_persistent_result = eLazyBoolYes;
  bool suppress_result = m_expr_options.ShouldSuppressResult(m_varobj_options);

  auto verbosity = GetDebugger().GetDWIMPrintVerbosity();

  Target &target = m_exe_ctx.GetTargetRef();

  EvaluateExpressionOptions eval_options =
      m_expr_options.GetEvaluateExpressionOptions(target, m_varobj_options);
  // This command manually removes the result variable, make sure expression
  // evaluation doesn't do it first.
  eval_options.SetSuppressPersistentResult(false);

  DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions(
      m_expr_options.m_verbosity, m_format_options.GetFormat());
  dump_options.SetHideRootName(suppress_result)
      .SetExpandPointerTypeFlags(lldb::eTypeIsObjC);

  bool is_po = m_varobj_options.use_object_desc;

  StackFrame *frame = m_exe_ctx.GetFramePtr();

  // Either the language was explicitly specified, or we check the frame.
  SourceLanguage language{m_expr_options.language};
  if (!language && frame)
    language = frame->GuessLanguage();

  // Add a hint if object description was requested, but no description
  // function was implemented.
  auto maybe_add_hint = [&](llvm::StringRef output) {
    static bool note_shown = false;
    if (note_shown)
      return;

    // Identify the default output of object description for Swift and
    // Objective-C
    // "<Name: 0x...>. The regex is:
    // - Start with "<".
    // - Capture 1 or more non-whitespace characters (the class name).
    // - Followed by ": 0x".
    // - Followed by 5 or more hex digits.
    // - Followed by ">".
    // - End with zero or more whitespace characters.
    static const std::regex swift_class_regex(
        "^<(\\S+): 0x[[:xdigit:]]{5,}>\\s*$");

    std::cmatch match;
    if (GetDebugger().GetShowDontUsePoHint() && !target.IsDummyTarget() &&
        (language.AsLanguageType() == lldb::eLanguageTypeSwift ||
         language.IsObjC()) &&
        std::regex_match(output.data(), match, swift_class_regex)) {

      result.AppendNoteWithFormatv(
          "{0} has no custom object description, use \"p\" to see its children",
          match[1].str());
      note_shown = true;
    }
  };

  // Dump `valobj` according to whether `po` was requested or not.
  auto dump_val_object = [&](ValueObject &valobj) {
    if (is_po) {
      StreamString temp_result_stream;
      if (llvm::Error error = valobj.Dump(temp_result_stream, dump_options)) {
        result.AppendError(toString(std::move(error)));
        return;
      }
      llvm::StringRef output = temp_result_stream.GetString();
      maybe_add_hint(output);
      result.GetOutputStream() << output;
    } else {
      llvm::Error error =
        valobj.Dump(result.GetOutputStream(), dump_options);
      if (error) {
        result.AppendError(toString(std::move(error)));
        return;
      }
    }
    m_interpreter.PrintWarningsIfNecessary(result.GetOutputStream(),
                                           m_cmd_name);
    result.SetStatus(eReturnStatusSuccessFinishResult);
  };

  // First, try `expr` as a _limited_ frame variable expression path: only the
  // dot operator (`.`) is permitted for this case.
  //
  // This is limited to support only unambiguous expression paths. Of note,
  // expression paths are not attempted if the expression contain either the
  // arrow operator (`->`) or the subscript operator (`[]`). This is because
  // both operators can be overloaded in C++, and could result in ambiguity in
  // how the expression is handled. Additionally, `*` and `&` are not supported.
  const bool try_variable_path =
      !expr.contains("->") && expr.find_first_of("*&[]") == StringRef::npos;
  if (frame && try_variable_path) {
    VariableSP var_sp;
    Status status;
    auto valobj_sp = frame->GetValueForVariableExpressionPath(
        expr, eval_options.GetUseDynamic(),
        StackFrame::eExpressionPathOptionsAllowDirectIVarAccess |
            StackFrame::eExpressionPathOptionsDisallowGlobals,
        var_sp, status, lldb::eDILModeSimple);
    if (valobj_sp && status.Success() && valobj_sp->GetError().Success()) {
      if (!suppress_result) {
        if (auto persisted_valobj = valobj_sp->Persist())
          valobj_sp = persisted_valobj;
      }

      if (verbosity == eDWIMPrintVerbosityFull) {
        StringRef flags;
        if (args.HasArgs())
          flags = args.GetArgString();
        result.AppendNoteWithFormatv("ran `frame variable {0}{1}`", flags,
                                     expr);
      }

      dump_val_object(*valobj_sp);
      return;
    }
  }

  // Second, try `expr` as a persistent variable.
  if (expr.starts_with("$"))
    if (auto *state = target.GetPersistentExpressionStateForLanguage(
            language.AsLanguageType()))
      if (auto var_sp = state->GetVariable(expr))
        if (auto valobj_sp = var_sp->GetValueObject()) {
          dump_val_object(*valobj_sp);
          return;
        }

  // Third, and lastly, try `expr` as a source expression to evaluate.
  {
    auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
    ValueObjectSP valobj_sp;
    std::string fixed_expression;

    ExpressionResults expr_result = target.EvaluateExpression(
        expr, exe_scope, valobj_sp, eval_options, &fixed_expression);

    if (valobj_sp)
      result.GetValueObjectList().Append(valobj_sp);

    // Record the position of the expression in the command.
    std::optional<uint16_t> indent;
    if (fixed_expression.empty()) {
      size_t pos = m_original_command.rfind(expr);
      if (pos != llvm::StringRef::npos)
        indent = pos;
    }
    // Previously the indent was set up for diagnosing command line
    // parsing errors. Now point it to the expression.
    result.SetDiagnosticIndent(indent);

    // Only mention Fix-Its if the expression evaluator applied them.
    // Compiler errors refer to the final expression after applying Fix-It(s).
    if (!fixed_expression.empty() && target.GetEnableNotifyAboutFixIts()) {
      Stream &error_stream = result.GetErrorStream();
      error_stream << "  Evaluated this expression after applying Fix-It(s):\n";
      error_stream << "    " << fixed_expression << "\n";
    }

    // If the expression failed, return an error.
    if (expr_result != eExpressionCompleted) {
      if (valobj_sp)
        result.SetError(valobj_sp->GetError().Clone());
      else
        result.AppendErrorWithFormatv(
            "unknown error evaluating expression `{0}`", expr);
      return;
    }

    if (verbosity != eDWIMPrintVerbosityNone) {
      StringRef flags;
      if (args.HasArgs())
        flags = args.GetArgStringWithDelimiter();
      result.AppendNoteWithFormatv("ran `expression {0}{1}`", flags, expr);
    }

    if (valobj_sp->GetError().GetError() != UserExpression::kNoResult)
      dump_val_object(*valobj_sp);
    else
      result.SetStatus(eReturnStatusSuccessFinishNoResult);

    if (suppress_result)
      if (auto result_var_sp =
              target.GetPersistentVariable(valobj_sp->GetName())) {
        auto language = valobj_sp->GetPreferredDisplayLanguage();
        if (auto *persistent_state =
                target.GetPersistentExpressionStateForLanguage(language))
          persistent_state->RemovePersistentVariable(result_var_sp);
      }
  }
}
