//===-- ScriptedHookPythonInterface.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-python.h"

#include "lldb/Core/PluginManager.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"

#include "../SWIGPythonBridge.h"
#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedHookPythonInterface.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::python;

ScriptedHookPythonInterface::ScriptedHookPythonInterface(
    ScriptInterpreterPythonImpl &interpreter)
    : ScriptedHookInterface(), ScriptedPythonInterface(interpreter) {}

ScriptedHookInterface::SupportedHookMethods
ScriptedHookPythonInterface::GetSupportedMethods() {
  SupportedHookMethods methods;
  // Qualify through ScriptedPythonInterface to resolve the diamond
  // inheritance (both ScriptedHookInterface and ScriptedPythonInterface
  // inherit ScriptedInterface which owns m_object_instance_sp).
  auto &obj_sp = ScriptedPythonInterface::m_object_instance_sp;
  if (!obj_sp)
    return methods;

  using Locker = ScriptInterpreterPythonImpl::Locker;
  Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
                 Locker::FreeLock);

  PythonObject implementor(PyRefType::Borrowed, (PyObject *)obj_sp->GetValue());
  if (!implementor.IsValid())
    return methods;

  methods.handle_module_loaded =
      implementor.HasAttribute("handle_module_loaded");
  methods.handle_module_unloaded =
      implementor.HasAttribute("handle_module_unloaded");
  methods.handle_stop = implementor.HasAttribute("handle_stop");
  return methods;
}

llvm::Expected<StructuredData::GenericSP>
ScriptedHookPythonInterface::CreatePluginObject(
    const ScriptedMetadata &scripted_metadata, lldb::TargetSP target_sp) {
  StructuredDataImpl args_sp(scripted_metadata.GetArgsSP());
  return ScriptedPythonInterface::CreatePluginObject(scripted_metadata, nullptr,
                                                     target_sp, args_sp);
}

llvm::Error
ScriptedHookPythonInterface::HandleModuleLoaded(lldb::StreamSP &output_sp) {
  return DispatchToOptional("handle_module_loaded", output_sp).takeError();
}

llvm::Error
ScriptedHookPythonInterface::HandleModuleUnloaded(lldb::StreamSP &output_sp) {
  return DispatchToOptional("handle_module_unloaded", output_sp).takeError();
}

llvm::Expected<bool>
ScriptedHookPythonInterface::HandleStop(ExecutionContext &exe_ctx,
                                        lldb::StreamSP &output_sp) {
  ExecutionContextRefSP exe_ctx_ref_sp =
      std::make_shared<ExecutionContextRef>(exe_ctx);
  llvm::Expected<StructuredData::ObjectSP> obj_or_err =
      Dispatch("handle_stop", exe_ctx_ref_sp, output_sp);
  if (!obj_or_err)
    return obj_or_err.takeError();

  // `handle_stop` is required, so a null object here means the hook returned
  // None: it expressed no preference, so stay stopped.
  StructuredData::ObjectSP obj = *obj_or_err;
  if (!obj || !obj->IsValid())
    return true;

  return obj->GetBooleanValue();
}

void ScriptedHookPythonInterface::Initialize() {
  const std::vector<llvm::StringRef> ci_usages = {
      "target hook add -P <script-name> [-k key -v value ...]"};
  const std::vector<llvm::StringRef> api_usages = {};
  PluginManager::RegisterPlugin(
      GetPluginNameStatic(),
      llvm::StringRef("Perform actions on target lifecycle events (module "
                      "load/unload, process stop)."),
      CreateInstance, eScriptedExtensionScriptedHook, eScriptLanguagePython,
      {ci_usages, api_usages});
}

void ScriptedHookPythonInterface::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}
