//===-- StackFrameRecognizer.cpp ------------------------------------------===//
//
// 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 "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Core/Architecture.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Interpreter/Interfaces/ScriptedStackFrameRecognizerInterface.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/ScriptedMetadata.h"
#include "llvm/Support/FormatVariadic.h"

using namespace lldb;
using namespace lldb_private;

class ScriptedRecognizedStackFrame : public RecognizedStackFrame {
public:
  ScriptedRecognizedStackFrame(ValueObjectListSP args, bool hidden,
                               lldb::StackFrameSP most_relevant_frame,
                               lldb::ValueObjectSP exception,
                               std::string stop_desc,
                               lldb::ThreadPlanSP step_through_plan_sp)
      : m_hidden(hidden), m_most_relevant_frame(std::move(most_relevant_frame)),
        m_exception(std::move(exception)),
        m_thread_plan_sp(std::move(step_through_plan_sp)) {
    m_arguments = std::move(args);
    m_stop_desc = std::move(stop_desc);
  }
  bool ShouldHide() override { return m_hidden; }
  lldb::StackFrameSP GetMostRelevantFrame() override {
    return m_most_relevant_frame;
  }
  lldb::ValueObjectSP GetExceptionObject() override { return m_exception; }

  lldb::ThreadPlanSP GetStepThroughPlan() override { return m_thread_plan_sp; }

protected:
  bool m_hidden;
  lldb::StackFrameSP m_most_relevant_frame;
  lldb::ValueObjectSP m_exception;
  lldb::ThreadPlanSP m_thread_plan_sp;
};

ScriptedStackFrameRecognizer::ScriptedStackFrameRecognizer(
    ScriptInterpreter *interpreter, const char *pclass)
    : m_python_class(pclass) {
  if (!interpreter)
    return;

  m_interface_sp = interpreter->CreateScriptedStackFrameRecognizerInterface();
  if (!m_interface_sp)
    return;

  ScriptedMetadata scripted_metadata(m_python_class, nullptr);
  auto obj_or_err = m_interface_sp->CreatePluginObject(scripted_metadata);
  if (!obj_or_err) {
    // CreatePluginObject has no error-return channel back to the command
    // handler that requested this recognizer, so report the detailed error
    // (which may include a Python backtrace) via the diagnostic system.
    Debugger::ReportError(
        llvm::formatv("failed to create ScriptedStackFrameRecognizer: {0}",
                      llvm::toString(obj_or_err.takeError()))
            .str(),
        interpreter->GetDebugger().GetID());
    m_interface_sp.reset();
  }
}

RecognizedStackFrameSP
ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {
  if (!m_interface_sp)
    return RecognizedStackFrameSP();

  ValueObjectListSP args = m_interface_sp->GetRecognizedArguments(frame);
  auto args_synthesized = std::make_shared<ValueObjectList>();
  if (args) {
    for (const auto &o : args->GetObjects())
      args_synthesized->Append(ValueObjectRecognizerSynthesizedValue::Create(
          *o, eValueTypeVariableArgument));
  }

  bool hidden = m_interface_sp->ShouldHide(frame);
  lldb::StackFrameSP most_relevant =
      m_interface_sp->SelectMostRelevantFrame(frame);
  lldb::ValueObjectSP exception = m_interface_sp->GetException(frame);
  std::string stop_desc = m_interface_sp->GetStopDescription(frame);
  // We only do step through if we're at the zeroth frame:
  lldb::ThreadPlanSP step_through_sp;
  if (frame->GetConcreteFrameIndex() == 0)
    step_through_sp = m_interface_sp->GetStepThroughPlan(frame->GetThread());

  return RecognizedStackFrameSP(new ScriptedRecognizedStackFrame(
      args_synthesized, hidden, std::move(most_relevant), std::move(exception),
      std::move(stop_desc), std::move(step_through_sp)));
}

void StackFrameRecognizerManager::BumpGeneration() {
  uint32_t n = m_generation;
  n = (n + 1) & ((1 << 16) - 1);
  m_generation = n;
}

void StackFrameRecognizerManager::AddRecognizer(
    StackFrameRecognizerSP recognizer, std::string module,
    std::vector<ConstString> symbols, Mangled::NamePreference symbol_mangling,
    bool first_instruction_only) {
  m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,
                            std::move(module), RegularExpressionSP(),
                            std::move(symbols), RegularExpressionSP(),
                            symbol_mangling, first_instruction_only, true});
  BumpGeneration();
}

void StackFrameRecognizerManager::AddRecognizer(
    StackFrameRecognizerSP recognizer, RegularExpressionSP module,
    RegularExpressionSP symbol, Mangled::NamePreference symbol_mangling,
    bool first_instruction_only) {
  m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, true,
                            std::string(), module, std::vector<ConstString>(),
                            symbol, symbol_mangling, first_instruction_only,
                            true});
  BumpGeneration();
}

void StackFrameRecognizerManager::ForEach(
    const std::function<void(
        uint32_t, bool, std::string, std::string, llvm::ArrayRef<ConstString>,
        Mangled::NamePreference name_preference, bool)> &callback) {
  for (auto entry : m_recognizers) {
    if (entry.is_regexp) {
      std::string module_name;
      std::string symbol_name;

      if (entry.module_regexp)
        module_name = entry.module_regexp->GetText().str();
      if (entry.symbol_regexp)
        symbol_name = entry.symbol_regexp->GetText().str();

      callback(entry.recognizer_id, entry.enabled, entry.recognizer->GetName(),
               module_name, llvm::ArrayRef(ConstString(symbol_name)),
               entry.symbol_mangling, true);
    } else {
      callback(entry.recognizer_id, entry.enabled, entry.recognizer->GetName(),
               entry.module, entry.symbols, entry.symbol_mangling, false);
    }
  }
}

bool StackFrameRecognizerManager::SetEnabledForID(uint32_t recognizer_id,
                                                  bool enabled) {
  auto found =
      llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {
        return e.recognizer_id == recognizer_id;
      });
  if (found == m_recognizers.end())
    return false;
  found->enabled = enabled;
  BumpGeneration();
  return true;
}

bool StackFrameRecognizerManager::RemoveRecognizerWithID(
    uint32_t recognizer_id) {
  auto found =
      llvm::find_if(m_recognizers, [recognizer_id](const RegisteredEntry &e) {
        return e.recognizer_id == recognizer_id;
      });
  if (found == m_recognizers.end())
    return false;
  m_recognizers.erase(found);
  BumpGeneration();
  return true;
}

void StackFrameRecognizerManager::RemoveAllRecognizers() {
  BumpGeneration();
  m_recognizers.clear();
}

StackFrameRecognizerSP
StackFrameRecognizerManager::GetRecognizerForFrame(StackFrameSP frame) {
  const SymbolContext &symctx = frame->GetSymbolContext(
      eSymbolContextModule | eSymbolContextFunction | eSymbolContextSymbol);
  ModuleSP module_sp = symctx.module_sp;
  if (!module_sp)
    return StackFrameRecognizerSP();
  llvm::StringRef module_name = module_sp->GetFileSpec().GetFilename();
  Address start_addr;
  if (symctx.symbol)
    start_addr = symctx.symbol->GetAddress();
  else if (symctx.function)
    start_addr = symctx.function->GetAddress();
  else
    return StackFrameRecognizerSP();
  Address current_addr = frame->GetFrameCodeAddress();

  // The symbol's start address may fall inside a non-executable function
  // header (as on WebAssembly), which no frame's PC can equal. Compare against
  // the first instruction instead.
  if (TargetSP target_sp = frame->CalculateTarget())
    if (Architecture *arch = target_sp->GetArchitecturePlugin())
      start_addr = arch->SkipFunctionHeader(start_addr);

  for (const auto &entry : m_recognizers) {
    if (!entry.enabled)
      continue;

    if (!entry.module.empty() && entry.module != module_name)
      continue;

    if (entry.module_regexp)
      if (!entry.module_regexp->Execute(module_name))
        continue;

    ConstString function_name = symctx.GetFunctionName(entry.symbol_mangling);

    if (!entry.symbols.empty())
      if (!llvm::is_contained(entry.symbols, function_name))
        continue;

    if (entry.symbol_regexp)
      if (!entry.symbol_regexp->Execute(function_name.GetStringRef()))
        continue;

    if (entry.first_instruction_only)
      if (start_addr != current_addr)
        continue;

    return entry.recognizer;
  }
  return StackFrameRecognizerSP();
}

RecognizedStackFrameSP
StackFrameRecognizerManager::RecognizeFrame(StackFrameSP frame) {
  auto recognizer = GetRecognizerForFrame(frame);
  if (!recognizer)
    return RecognizedStackFrameSP();
  return recognizer->RecognizeFrame(frame);
}
