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

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

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

#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(
    const ScriptedMetadata &scripted_metadata, ExecutionContext &exe_ctx,
    StructuredData::Generic *script_obj) {
  ExecutionContextRefSP exe_ctx_ref_sp =
      std::make_shared<ExecutionContextRef>(exe_ctx);
  return ScriptedPythonInterface::CreatePluginObject(
      scripted_metadata, script_obj, exe_ctx_ref_sp,
      scripted_metadata.GetArgsSP());
}

StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() {
  StructuredData::DictionarySP dict =
      LogAndDefault(Dispatch<StructuredData::DictionarySP>("get_capabilities"),
                    LLVM_PRETTY_FUNCTION);
  if (!dict)
    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) {
  llvm::Expected<std::optional<MemoryRegionInfo>> mem_region_or_err =
      Dispatch<std::optional<MemoryRegionInfo>>(
          "get_memory_region_containing_address", address);
  if (!mem_region_or_err) {
    error = Status::FromError(mem_region_or_err.takeError());
    return {};
  }

  return *mem_region_or_err;
}

StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() {
  StructuredData::DictionarySP dict =
      LogAndDefault(Dispatch<StructuredData::DictionarySP>("get_threads_info"),
                    LLVM_PRETTY_FUNCTION);
  if (!dict)
    return {};

  return dict;
}

bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr,
                                                      Status &error) {
  llvm::Expected<StructuredData::ObjectSP> obj_or_err =
      Dispatch("create_breakpoint", addr, error);
  // If there was an error on the python call, surface it to the user.
  if (!obj_or_err) {
    error = Status::FromError(obj_or_err.takeError());
    return {};
  }

  StructuredData::ObjectSP obj = *obj_or_err;
  if (!obj || !obj->IsValid())
    return {};

  return obj->GetBooleanValue();
}

lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress(
    lldb::addr_t address, size_t size, Status &error) {
  llvm::Expected<lldb::DataExtractorSP> data_or_err =
      Dispatch<lldb::DataExtractorSP>("read_memory_at_address", address, size,
                                      error);
  // If there was an error on the python call, surface it to the user.
  if (!data_or_err) {
    error = Status::FromError(data_or_err.takeError());
    return {};
  }

  return *data_or_err;
}

lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress(
    lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) {
  llvm::Expected<StructuredData::ObjectSP> obj_or_err =
      Dispatch("write_memory_at_address", addr, data_sp, error);
  // If there was an error on the python call, surface it to the user.
  if (!obj_or_err) {
    error = Status::FromError(obj_or_err.takeError());
    return LLDB_INVALID_OFFSET;
  }

  StructuredData::ObjectSP obj = *obj_or_err;
  if (!obj || !obj->IsValid())
    return LLDB_INVALID_OFFSET;

  return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET);
}

StructuredData::ArraySP ScriptedProcessPythonInterface::GetLoadedImages() {
  StructuredData::ArraySP array =
      LogAndDefault(Dispatch<StructuredData::ArraySP>("get_loaded_images"),
                    LLVM_PRETTY_FUNCTION);
  if (!array)
    return {};

  return array;
}

lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() {
  StructuredData::ObjectSP obj =
      LogAndDefault(Dispatch("get_process_id"), LLVM_PRETTY_FUNCTION);
  if (!obj)
    return LLDB_INVALID_PROCESS_ID;

  return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID);
}

bool ScriptedProcessPythonInterface::IsAlive() {
  StructuredData::ObjectSP obj =
      LogAndDefault(Dispatch("is_alive"), LLVM_PRETTY_FUNCTION);
  if (!obj)
    return {};

  return obj->GetBooleanValue();
}

std::optional<std::string>
ScriptedProcessPythonInterface::GetScriptedThreadPluginName() {
  StructuredData::ObjectSP obj = LogAndDefault(
      Dispatch("get_scripted_thread_plugin"), LLVM_PRETTY_FUNCTION);
  if (!obj)
    return {};

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

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

StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
  StructuredData::DictionarySP dict = LogAndDefault(
      Dispatch<StructuredData::DictionarySP>("get_process_metadata"),
      LLVM_PRETTY_FUNCTION);
  if (!dict)
    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, eScriptedExtensionScriptedProcess, eScriptLanguagePython,
      {ci_usages, api_usages});
}

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