//===-- 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, ConstString module,
    llvm::ArrayRef<ConstString> symbols,
    Mangled::NamePreference symbol_mangling, bool first_instruction_only) {
  m_recognizers.push_front({(uint32_t)m_recognizers.size(), recognizer, false,
                            module, RegularExpressionSP(), 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,
                            ConstString(), 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.GetCString(), 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)
      if (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);
}
