//===-- ScriptedProcessPythonInterface.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/Core/PluginManager.h"
#include "lldb/Host/Config.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"

#if LLDB_ENABLE_PYTHON

// clang-format off
// LLDB Python header must be included first
#include "../lldb-python.h"

#include "../SWIGPythonBridge.h"
#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedThreadPythonInterface.h"
#include "ScriptedProcessPythonInterface.h"

// Included in this position to prevent redefinition of pid_t on Windows.
#include "lldb/Target/Process.h"
//clang-format off

#include <optional>

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::python;
using Locker = ScriptInterpreterPythonImpl::Locker;

ScriptedProcessPythonInterface::ScriptedProcessPythonInterface(
    ScriptInterpreterPythonImpl &interpreter)
    : ScriptedProcessInterface(), ScriptedPythonInterface(interpreter) {}

llvm::Expected<StructuredData::GenericSP>
ScriptedProcessPythonInterface::CreatePluginObject(
    llvm::StringRef class_name, ExecutionContext &exe_ctx,
    StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj) {
  ExecutionContextRefSP exe_ctx_ref_sp =
      std::make_shared<ExecutionContextRef>(exe_ctx);
  StructuredDataImpl sd_impl(args_sp);
  return ScriptedPythonInterface::CreatePluginObject(class_name, script_obj,
                                                     exe_ctx_ref_sp, sd_impl);
}

StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
  Status error;
  StructuredData::DictionarySP dict =
      Dispatch<StructuredData::DictionarySP>("get_capabilities", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
                                                    error))
    return {};

  return dict;
}

Status
ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) {
  lldb::ProcessAttachInfoSP attach_info_sp =
      std::make_shared<ProcessAttachInfo>(attach_info);
  return GetStatusFromMethod("attach", attach_info_sp);
}

Status ScriptedProcessPythonInterface::Launch() {
  return GetStatusFromMethod("launch");
}

Status ScriptedProcessPythonInterface::Resume() {
  // When calling ScriptedProcess.Resume from lldb we should always stop.
  return GetStatusFromMethod("resume", /*should_stop=*/true);
}

std::optional<MemoryRegionInfo>
ScriptedProcessPythonInterface::GetMemoryRegionContainingAddress(
    lldb::addr_t address, Status &error) {
  auto mem_region = Dispatch<std::optional<MemoryRegionInfo>>(
      "get_memory_region_containing_address", error, address);

  if (error.Fail()) {
    return ErrorWithMessage<MemoryRegionInfo>(LLVM_PRETTY_FUNCTION,
                                              error.AsCString(), error);
  }

  return mem_region;
}

StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
  Status error;
  StructuredData::DictionarySP dict =
      Dispatch<StructuredData::DictionarySP>("get_threads_info", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
                                                    error))
    return {};

  return dict;
}

bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr,
                                                      Status &error) {
  Status py_error;
  StructuredData::ObjectSP obj =
      Dispatch("create_breakpoint", py_error, addr, error);

  // If there was an error on the python call, surface it to the user.
  if (py_error.Fail())
    error = std::move(py_error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error))
    return {};

  return obj->GetBooleanValue();
}

lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
    lldb::addr_t address, size_t size, Status &error) {
  Status py_error;
  lldb::DataExtractorSP data_sp = Dispatch<lldb::DataExtractorSP>(
      "read_memory_at_address", py_error, address, size, error);

  // If there was an error on the python call, surface it to the user.
  if (py_error.Fail())
    error = std::move(py_error);

  return data_sp;
}

lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
    lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) {
  Status py_error;
  StructuredData::ObjectSP obj =
      Dispatch("write_memory_at_address", py_error, addr, data_sp, error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error))
    return LLDB_INVALID_OFFSET;

  // If there was an error on the python call, surface it to the user.
  if (py_error.Fail())
    error = std::move(py_error);

  return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
}

StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
  Status error;
  StructuredData::ArraySP array =
      Dispatch<StructuredData::ArraySP>("get_loaded_images", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array,
                                                    error))
    return {};

  return array;
}

lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
  Status error;
  StructuredData::ObjectSP obj = Dispatch("get_process_id", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error))
    return LLDB_INVALID_PROCESS_ID;

  return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
}

bool ScriptedProcessPythonInterface::IsAlive() {
  Status error;
  StructuredData::ObjectSP obj = Dispatch("is_alive", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error))
    return {};

  return obj->GetBooleanValue();
}

std::optional<std::string>
ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
  Status error;
  StructuredData::ObjectSP obj = Dispatch("get_scripted_thread_plugin", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error))
    return {};

  return obj->GetStringValue().str();
}

lldb::ScriptedThreadInterfaceSP
ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
  return m_interpreter.CreateScriptedThreadInterface();
}

StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
  Status error;
  StructuredData::DictionarySP dict =
      Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict,
                                                    error))
    return {};

  return dict;
}

void ScriptedProcessPythonInterface::Initialize() {
  const std::vector<llvm::StringRef> ci_usages = {
      "process attach -C <script-name> [-k key -v value ...]",
      "process launch -C <script-name> [-k key -v value ...]"};
  const std::vector<llvm::StringRef> api_usages = {
      "SBAttachInfo.SetScriptedProcessClassName",
      "SBAttachInfo.SetScriptedProcessDictionary",
      "SBTarget.Attach",
      "SBLaunchInfo.SetScriptedProcessClassName",
      "SBLaunchInfo.SetScriptedProcessDictionary",
      "SBTarget.Launch"};
  PluginManager::RegisterPlugin(
      GetPluginNameStatic(), llvm::StringRef("Mock process state"),
      CreateInstance, eScriptLanguagePython, {ci_usages, api_usages});
}

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

#endif
