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

#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"

#include "lldb/Host/OptionParser.h"

#include "lldb/Interpreter/OptionArgParser.h"
#include "lldb/Interpreter/OptionGroupBoolean.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Target/MemoryRegionInfo.h"

LLDB_PLUGIN_DEFINE(ScriptedProcess)

using namespace lldb;
using namespace lldb_private;

ConstString ScriptedProcess::GetPluginNameStatic() {
  static ConstString g_name("ScriptedProcess");
  return g_name;
}

const char *ScriptedProcess::GetPluginDescriptionStatic() {
  return "Scripted Process plug-in.";
}

lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp,
                                                lldb::ListenerSP listener_sp,
                                                const FileSpec *file,
                                                bool can_connect) {
  ScriptedProcess::LaunchInfo launch_info(target_sp->GetProcessLaunchInfo());

  auto process_sp =
      std::make_shared<ScriptedProcess>(target_sp, listener_sp, launch_info);

  if (!process_sp || !process_sp->m_script_object_sp ||
      !process_sp->m_script_object_sp->IsValid())
    return nullptr;

  return process_sp;
}

bool ScriptedProcess::CanDebug(lldb::TargetSP target_sp,
                               bool plugin_specified_by_name) {
  return true;
}

ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp,
                                 lldb::ListenerSP listener_sp,
                                 const ScriptedProcess::LaunchInfo &launch_info)
    : Process(target_sp, listener_sp), m_launch_info(launch_info),
      m_interpreter(nullptr), m_script_object_sp(nullptr) {
  if (!target_sp)
    return;

  m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();

  if (!m_interpreter)
    return;

  StructuredData::ObjectSP object_sp = GetInterface().CreatePluginObject(
      m_launch_info.GetClassName().c_str(), target_sp,
      m_launch_info.GetDictionarySP());

  if (object_sp && object_sp->IsValid())
    m_script_object_sp = object_sp;
}

ScriptedProcess::~ScriptedProcess() {
  Clear();
  // We need to call finalize on the process before destroying ourselves to
  // make sure all of the broadcaster cleanup goes as planned. If we destruct
  // this class, then Process::~Process() might have problems trying to fully
  // destroy the broadcaster.
  Finalize();
}

void ScriptedProcess::Initialize() {
  static llvm::once_flag g_once_flag;

  llvm::call_once(g_once_flag, []() {
    PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                  GetPluginDescriptionStatic(), CreateInstance);
  });
}

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

ConstString ScriptedProcess::GetPluginName() { return GetPluginNameStatic(); }

uint32_t ScriptedProcess::GetPluginVersion() { return 1; }

Status ScriptedProcess::DoLoadCore() {
  ProcessLaunchInfo launch_info = GetTarget().GetProcessLaunchInfo();

  return DoLaunch(nullptr, launch_info);
}

Status ScriptedProcess::DoLaunch(Module *exe_module,
                                 ProcessLaunchInfo &launch_info) {
  if (!m_interpreter)
    return Status("No interpreter.");

  if (!m_script_object_sp)
    return Status("No python object.");

  Status status = GetInterface().Launch();

  if (status.Success()) {
    SetPrivateState(eStateRunning);
    SetPrivateState(eStateStopped);
  }

  return status;
};

void ScriptedProcess::DidLaunch() {
  if (m_interpreter)
    m_pid = GetInterface().GetProcessID();
}

Status ScriptedProcess::DoResume() {
  if (!m_interpreter)
    return Status("No interpreter.");

  if (!m_script_object_sp)
    return Status("No python object.");

  Status status = GetInterface().Resume();

  if (status.Success()) {
    SetPrivateState(eStateRunning);
    SetPrivateState(eStateStopped);
  }

  return status;
}

Status ScriptedProcess::DoDestroy() { return Status(); }

bool ScriptedProcess::IsAlive() {
  if (!m_interpreter)
    return false;

  return GetInterface().IsAlive();
}

size_t ScriptedProcess::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
                                   Status &error) {
  return DoReadMemory(addr, buf, size, error);
}

size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
                                     Status &error) {

  auto error_with_message = [&error](llvm::StringRef message) {
    error.SetErrorString(message);
    return LLDB_INVALID_ADDRESS;
  };

  if (!m_interpreter)
    return error_with_message("No interpreter.");

  lldb::DataExtractorSP data_extractor_sp =
      GetInterface().ReadMemoryAtAddress(addr, size, error);

  if (!data_extractor_sp || error.Fail())
    return LLDB_INVALID_ADDRESS;

  if (data_extractor_sp->GetByteSize() != size)
    return error_with_message("Failed to read requested memory size.");

  offset_t bytes_copied = data_extractor_sp->CopyByteOrderedData(
      0, size, buf, size, GetByteOrder());

  if (!bytes_copied || bytes_copied == LLDB_INVALID_OFFSET)
    return error_with_message("Failed to copy read memory to buffer.");

  return size;
}

ArchSpec ScriptedProcess::GetArchitecture() {
  return GetTarget().GetArchitecture();
}

Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
                                            MemoryRegionInfo &region) {
  return Status();
}

Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos &region_list) {
  Status error;

  if (!m_interpreter) {
    error.SetErrorString("No interpreter.");
    return error;
  }

  lldb::addr_t address = 0;
  lldb::MemoryRegionInfoSP mem_region_sp = nullptr;

  while ((mem_region_sp =
              GetInterface().GetMemoryRegionContainingAddress(address))) {
    auto range = mem_region_sp->GetRange();
    address += range.GetRangeBase() + range.GetByteSize();
    region_list.push_back(*mem_region_sp.get());
  }

  return error;
}

void ScriptedProcess::Clear() { Process::m_thread_list.Clear(); }

bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list,
                                         ThreadList &new_thread_list) {
  return new_thread_list.GetSize(false) > 0;
}

bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) {
  info.Clear();
  info.SetProcessID(GetID());
  info.SetArchitecture(GetArchitecture());
  lldb::ModuleSP module_sp = GetTarget().GetExecutableModule();
  if (module_sp) {
    const bool add_exe_file_as_first_arg = false;
    info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
                           add_exe_file_as_first_arg);
  }
  return true;
}

ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
  return m_interpreter->GetScriptedProcessInterface();
}
