//===-- StackFrameRecognizer.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 <vector>
#include "lldb/Core/Module.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Utility/RegularExpression.h"

using namespace lldb;
using namespace lldb_private;

#ifndef LLDB_DISABLE_PYTHON

class ScriptedRecognizedStackFrame : public RecognizedStackFrame {
public:
  ScriptedRecognizedStackFrame(ValueObjectListSP args) {
    m_arguments = args;
  }
};

ScriptedStackFrameRecognizer::ScriptedStackFrameRecognizer(
    ScriptInterpreter *interpreter, const char *pclass)
    : m_interpreter(interpreter), m_python_class(pclass) {
  m_python_object_sp =
      m_interpreter->CreateFrameRecognizer(m_python_class.c_str());
}

RecognizedStackFrameSP
ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) {
  if (!m_python_object_sp || !m_interpreter)
    return RecognizedStackFrameSP();

  ValueObjectListSP args =
      m_interpreter->GetRecognizedArguments(m_python_object_sp, frame);
  auto args_synthesized = ValueObjectListSP(new ValueObjectList());
  for (const auto o : args->GetObjects()) {
    args_synthesized->Append(ValueObjectRecognizerSynthesizedValue::Create(
        *o, eValueTypeVariableArgument));
  }

  return RecognizedStackFrameSP(
      new ScriptedRecognizedStackFrame(args_synthesized));
}

#endif

class StackFrameRecognizerManagerImpl {
public:
  void AddRecognizer(StackFrameRecognizerSP recognizer,
                     const ConstString &module, const ConstString &symbol,
                     bool first_instruction_only) {
    m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(),
                              symbol, RegularExpressionSP(),
                              first_instruction_only});
  }

  void AddRecognizer(StackFrameRecognizerSP recognizer,
                     RegularExpressionSP module, RegularExpressionSP symbol,
                     bool first_instruction_only) {
    m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), module,
                              ConstString(), symbol, first_instruction_only});
  }

  void ForEach(
      std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
                         std::string symbol, bool regexp)> const &callback) {
    for (auto entry : m_recognizers) {
      if (entry.is_regexp) {
        callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module_regexp->GetText(),
                 entry.symbol_regexp->GetText(), true);
      } else {
        callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(),
                 entry.symbol.GetCString(), false);
      }
    }
  }

  bool RemoveRecognizerWithID(uint32_t recognizer_id) {
    if (recognizer_id >= m_recognizers.size()) return false;
    if (m_recognizers[recognizer_id].deleted) return false;
    m_recognizers[recognizer_id].deleted = true;
    return true;
  }

  void RemoveAllRecognizers() {
    m_recognizers.clear();
  }

  StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) {
    const SymbolContext &symctx =
        frame->GetSymbolContext(eSymbolContextModule | eSymbolContextFunction);
    ConstString function_name = symctx.GetFunctionName();
    ModuleSP module_sp = symctx.module_sp;
    if (!module_sp) return StackFrameRecognizerSP();
    ConstString module_name = module_sp->GetFileSpec().GetFilename();
    Symbol *symbol = symctx.symbol;
    if (!symbol) return StackFrameRecognizerSP();
    Address start_addr = symbol->GetAddress();
    Address current_addr = frame->GetFrameCodeAddress();

    for (auto entry : m_recognizers) {
      if (entry.deleted) continue;
      if (entry.module)
        if (entry.module != module_name) continue;

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

      if (entry.symbol)
        if (entry.symbol != 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 RecognizeFrame(StackFrameSP frame) {
    auto recognizer = GetRecognizerForFrame(frame);
    if (!recognizer) return RecognizedStackFrameSP();
    return recognizer->RecognizeFrame(frame);
  }

 private:
  struct RegisteredEntry {
    uint32_t recognizer_id;
    bool deleted;
    StackFrameRecognizerSP recognizer;
    bool is_regexp;
    ConstString module;
    RegularExpressionSP module_regexp;
    ConstString symbol;
    RegularExpressionSP symbol_regexp;
    bool first_instruction_only;
  };

  std::deque<RegisteredEntry> m_recognizers;
};

StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() {
  static StackFrameRecognizerManagerImpl instance =
      StackFrameRecognizerManagerImpl();
  return instance;
}

void StackFrameRecognizerManager::AddRecognizer(
    StackFrameRecognizerSP recognizer, const ConstString &module,
    const ConstString &symbol, bool first_instruction_only) {
  GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
                                                     first_instruction_only);
}

void StackFrameRecognizerManager::AddRecognizer(
    StackFrameRecognizerSP recognizer, RegularExpressionSP module,
    RegularExpressionSP symbol, bool first_instruction_only) {
  GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol,
                                                     first_instruction_only);
}

void StackFrameRecognizerManager::ForEach(
    std::function<void(uint32_t recognized_id, std::string recognizer_name, std::string module,
                       std::string symbol, bool regexp)> const &callback) {
  GetStackFrameRecognizerManagerImpl().ForEach(callback);
}

void StackFrameRecognizerManager::RemoveAllRecognizers() {
  GetStackFrameRecognizerManagerImpl().RemoveAllRecognizers();
}

bool StackFrameRecognizerManager::RemoveRecognizerWithID(uint32_t recognizer_id) {
  return GetStackFrameRecognizerManagerImpl().RemoveRecognizerWithID(recognizer_id);
}

RecognizedStackFrameSP StackFrameRecognizerManager::RecognizeFrame(
    StackFrameSP frame) {
  return GetStackFrameRecognizerManagerImpl().RecognizeFrame(frame);
}

StackFrameRecognizerSP StackFrameRecognizerManager::GetRecognizerForFrame(
    lldb::StackFrameSP frame) {
  return GetStackFrameRecognizerManagerImpl().GetRecognizerForFrame(frame);
}
