// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "WasmVendorPlugins.h"

#include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/linux/HostInfoLinux.h"
#include "lldb/Target/Platform.h"
#include "lldb/Utility/RegisterValue.h"

namespace symbols_backend {

void WasmPlatform::Initialize() {
  lldb_private::Platform::SetHostPlatform(
      std::make_shared<WasmPlatform>(/*is_host_platform*/ true));
}
void WasmPlatform::Terminate() {}

WasmRegisters::WasmRegisters(lldb_private::Thread& thread, size_t frame_offset)
    : RegisterContext(thread, 0), frame_offset_(frame_offset) {
  fake_pc_register_.kinds[lldb::eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
}

const lldb_private::RegisterInfo* WasmRegisters::GetRegisterInfoAtIndex(
    size_t reg) {
  if (reg == 0) {
    return &fake_pc_register_;
  }
  return nullptr;
}

bool WasmRegisters::ReadRegister(const lldb_private::RegisterInfo* reg_info,
                                 lldb_private::RegisterValue& reg_value) {
  if (reg_info == &fake_pc_register_) {
    reg_value = static_cast<uint32_t>(frame_offset_);
    return true;
  }
  return false;
}

bool WasmUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx,
                                       lldb::addr_t& cfa,
                                       lldb::addr_t& pc,
                                       bool& behaves_like_zeroth_frame) {
  if (frame_idx != 0) {
    return false;
  }
  pc = frame_offset_;
  cfa = LLDB_INVALID_ADDRESS;
  behaves_like_zeroth_frame = true;
  return true;
}

lldb::RegisterContextSP WasmThread::CreateRegisterContextForFrame(
    lldb_private::StackFrame* frame) {
  return unwind_.DoCreateRegisterContextForFrame(frame);
}

lldb::RegisterContextSP WasmThread::GetRegisterContext() {
  return unwind_.GetRegisterContext();
}

lldb::StackFrameSP WasmThread::GetFrame() {
  if (!stack_frame_) {
    stack_frame_ = this->GetStackFrameList()->GetFrameAtIndex(0);
    this->SetSelectedFrame(stack_frame_.get());
  }
  return stack_frame_;
}

void WasmProcess::SetProxyAndFrameOffset(const api::DebuggerProxy& proxy,
                                         size_t frame_offset) {
  proxy_ = &proxy;
  frame_offset_ = frame_offset;
  this->SetPrivateState(lldb::StateType::eStateStopped);
}
bool WasmProcess::CanDebug(lldb::TargetSP target,
                           bool plugin_specified_by_name) {
  return target->GetArchitecture().GetTriple().getArchName() == "wasm32";
}
bool WasmProcess::DoUpdateThreadList(
    lldb_private::ThreadList& old_thread_list,
    lldb_private::ThreadList& new_thread_list) {
  if (frame_offset_ > 0) {
    new_thread_list.AddThread(
        lldb::ThreadSP(new WasmThread(*this, frame_offset_)));
    return true;
  }
  return false;
}

size_t WasmProcess::DoReadMemory(lldb::addr_t vm_addr,
                                 void* buf,
                                 size_t size,
                                 lldb_private::Status& error) {
  if (!proxy_) {
    error.SetErrorString("Proxy not initialized");
    return 0;
  }
  auto result = proxy_->ReadMemory(vm_addr, buf, size);
  if (!result) {
    error.SetErrorString(llvm::toString(result.takeError()));
    return 0;
  }
  return *result;
}

void WasmProcess::Initialize() {
  lldb_private::PluginManager::RegisterPlugin(
      GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance);
}

lldb::ProcessSP WasmProcess::CreateInstance(
    lldb::TargetSP target_sp,
    lldb::ListenerSP listener_sp,
    const lldb_private::FileSpec* crash_file_path,
    bool can_connect) {
  return lldb::ProcessSP(new WasmProcess(target_sp, listener_sp));
}

void WasmProcess::Terminate() {
  lldb_private::PluginManager::UnregisterPlugin(CreateInstance);
}

char SymbolFileWasmDWARF::ID;

void SymbolFileWasmDWARF::Initialize() {
  lldb_private::LogChannelDWARF::Initialize();
  lldb_private::PluginManager::RegisterPlugin(
      GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
      SymbolFileDWARF::DebuggerInitialize);
}

void SymbolFileWasmDWARF::Terminate() {
  lldb_private::PluginManager::UnregisterPlugin(CreateInstance);
  lldb_private::LogChannelDWARF::Terminate();
}

llvm::StringRef SymbolFileWasmDWARF::GetPluginDescriptionStatic() {
  return "Wasm DWARF";
}

lldb_private::SymbolFile* SymbolFileWasmDWARF::CreateInstance(
    lldb::ObjectFileSP objfile_sp) {
  return new SymbolFileWasmDWARF(std::move(objfile_sp),
                                 /*dwo_section_list*/ nullptr);
}
}  // namespace symbols_backend

LLDB_PLUGIN_DEFINE_ADV(symbols_backend::SymbolFileWasmDWARF,
                       SymbolFileWasmDWARF)

namespace lldb_private {
void HostInfoLinux::ComputeHostArchitectureSupport(ArchSpec& arch_32,
                                                   ArchSpec& arch_64) {
  HostInfoPosix::ComputeHostArchitectureSupport(arch_32, arch_64);
}

bool HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec& file_spec) {
  return false;
}

bool HostInfoLinux::ComputeUserPluginsDirectory(FileSpec& file_spec) {
  return false;
}

Environment Host::GetEnvironment() {
  return {};
}
}  // namespace lldb_private
