//===-- 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;

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));
}

class StackFrameRecognizerManagerImpl {
public:
  void AddRecognizer(StackFrameRecognizerSP recognizer,
                     ConstString module, 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, ConstString module,
    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);
}
