//===----------------------------------------------------------------------===//
//
// 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 "ScriptedFrame.h"
#include "Plugins/Process/Utility/RegisterContextMemory.h"

#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Expression/DWARFExpressionList.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Interpreter/Interfaces/ScriptedFrameInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedInterface.h"
#include "lldb/Interpreter/Interfaces/ScriptedThreadInterface.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/DynamicRegisterInfo.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StructuredData.h"
#include "lldb/Utility/ValueType.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectList.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "llvm/Support/ErrorHandling.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

char ScriptedFrame::ID;

void ScriptedFrame::CheckInterpreterAndScriptObject() const {
  lldbassert(m_script_object_sp && "Invalid Script Object.");
  lldbassert(GetInterface() && "Invalid Scripted Frame Interface.");
}

llvm::Expected<std::shared_ptr<ScriptedFrame>>
ScriptedFrame::Create(ThreadSP thread_sp,
                      ScriptedThreadInterfaceSP scripted_thread_interface_sp,
                      StructuredData::DictionarySP args_sp,
                      StructuredData::Generic *script_object) {
  if (!thread_sp || !thread_sp->IsValid())
    return llvm::createStringError("invalid thread");

  ProcessSP process_sp = thread_sp->GetProcess();
  if (!process_sp || !process_sp->IsValid())
    return llvm::createStringError("invalid process");

  ScriptInterpreter *script_interp =
      process_sp->GetTarget().GetDebugger().GetScriptInterpreter();
  if (!script_interp)
    return llvm::createStringError("no script interpreter");

  auto scripted_frame_interface = script_interp->CreateScriptedFrameInterface();
  if (!scripted_frame_interface)
    return llvm::createStringError("failed to create scripted frame interface");

  llvm::StringRef frame_class_name;
  if (!script_object) {
    // If no script object is provided and we have a scripted thread interface,
    // try to get the frame class name from it.
    if (scripted_thread_interface_sp) {
      std::optional<std::string> class_name =
          scripted_thread_interface_sp->GetScriptedFramePluginName();
      if (!class_name || class_name->empty())
        return llvm::createStringError(
            "failed to get scripted frame class name");
      frame_class_name = *class_name;
    } else {
      return llvm::createStringError(
          "no script object provided and no scripted thread interface");
    }
  }

  ExecutionContext exe_ctx(thread_sp);
  auto obj_or_err = scripted_frame_interface->CreatePluginObject(
      frame_class_name, exe_ctx, args_sp, script_object);

  if (!obj_or_err)
    return llvm::createStringError(
        "failed to create script object: %s",
        llvm::toString(obj_or_err.takeError()).c_str());

  StructuredData::GenericSP owned_script_object_sp = *obj_or_err;

  if (!owned_script_object_sp->IsValid())
    return llvm::createStringError("created script object is invalid");

  lldb::user_id_t frame_id = scripted_frame_interface->GetID();

  lldb::addr_t pc = scripted_frame_interface->GetPC();
  SymbolContext sc;
  Address symbol_addr;
  if (pc != LLDB_INVALID_ADDRESS) {
    symbol_addr.SetLoadAddress(pc, &process_sp->GetTarget());
    symbol_addr.CalculateSymbolContext(&sc);
  }

  std::optional<SymbolContext> maybe_sym_ctx =
      scripted_frame_interface->GetSymbolContext();
  if (maybe_sym_ctx)
    sc = *maybe_sym_ctx;

  lldb::RegisterContextSP reg_ctx_sp;
  auto regs_or_err =
      CreateRegisterContext(*scripted_frame_interface, *thread_sp, frame_id);
  if (!regs_or_err)
    LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), regs_or_err.takeError(), "{0}");
  else
    reg_ctx_sp = *regs_or_err;

  return std::make_shared<ScriptedFrame>(thread_sp, scripted_frame_interface,
                                         frame_id, pc, sc, reg_ctx_sp,
                                         owned_script_object_sp);
}

ScriptedFrame::ScriptedFrame(ThreadSP thread_sp,
                             ScriptedFrameInterfaceSP interface_sp,
                             lldb::user_id_t id, lldb::addr_t pc,
                             SymbolContext &sym_ctx,
                             lldb::RegisterContextSP reg_ctx_sp,
                             StructuredData::GenericSP script_object_sp)
    : StackFrame(thread_sp, /*frame_idx=*/id,
                 /*concrete_frame_idx=*/id, /*reg_context_sp=*/reg_ctx_sp,
                 /*cfa=*/0, /*pc=*/pc,
                 /*behaves_like_zeroth_frame=*/!id, /*symbol_ctx=*/&sym_ctx),
      m_scripted_frame_interface_sp(interface_sp),
      m_script_object_sp(script_object_sp) {
  // FIXME: This should be part of the base class constructor.
  m_stack_frame_kind = StackFrame::Kind::Synthetic;
}

ScriptedFrame::~ScriptedFrame() {}

const char *ScriptedFrame::GetFunctionName() {
  CheckInterpreterAndScriptObject();
  std::optional<std::string> function_name = GetInterface()->GetFunctionName();
  if (!function_name)
    return StackFrame::GetFunctionName();
  return ConstString(function_name->c_str()).AsCString(nullptr);
}

const char *ScriptedFrame::GetDisplayFunctionName() {
  CheckInterpreterAndScriptObject();
  std::optional<std::string> function_name =
      GetInterface()->GetDisplayFunctionName();
  if (!function_name)
    return StackFrame::GetDisplayFunctionName();
  return ConstString(function_name->c_str()).AsCString(nullptr);
}

bool ScriptedFrame::IsInlined() { return GetInterface()->IsInlined(); }

bool ScriptedFrame::IsArtificial() const {
  return GetInterface()->IsArtificial();
}

bool ScriptedFrame::IsHidden() { return GetInterface()->IsHidden(); }

lldb::ScriptedFrameInterfaceSP ScriptedFrame::GetInterface() const {
  return m_scripted_frame_interface_sp;
}

std::shared_ptr<DynamicRegisterInfo> ScriptedFrame::GetDynamicRegisterInfo() {
  CheckInterpreterAndScriptObject();

  StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();

  Status error;
  if (!reg_info)
    return ScriptedInterface::ErrorWithMessage<
        std::shared_ptr<DynamicRegisterInfo>>(
        LLVM_PRETTY_FUNCTION, "failed to get scripted frame registers info",
        error, LLDBLog::Thread);

  ThreadSP thread_sp = m_thread_wp.lock();
  if (!thread_sp || !thread_sp->IsValid())
    return ScriptedInterface::ErrorWithMessage<
        std::shared_ptr<DynamicRegisterInfo>>(
        LLVM_PRETTY_FUNCTION,
        "failed to get scripted frame registers info: invalid thread", error,
        LLDBLog::Thread);

  ProcessSP process_sp = thread_sp->GetProcess();
  if (!process_sp || !process_sp->IsValid())
    return ScriptedInterface::ErrorWithMessage<
        std::shared_ptr<DynamicRegisterInfo>>(
        LLVM_PRETTY_FUNCTION,
        "failed to get scripted frame registers info: invalid process", error,
        LLDBLog::Thread);

  return DynamicRegisterInfo::Create(*reg_info,
                                     process_sp->GetTarget().GetArchitecture());
}

llvm::Expected<lldb::RegisterContextSP>
ScriptedFrame::CreateRegisterContext(ScriptedFrameInterface &interface,
                                     Thread &thread, lldb::user_id_t frame_id) {
  StructuredData::DictionarySP reg_info = interface.GetRegisterInfo();

  if (!reg_info)
    return llvm::createStringError(
        "failed to get scripted frame registers info");

  std::shared_ptr<DynamicRegisterInfo> register_info_sp =
      DynamicRegisterInfo::Create(
          *reg_info, thread.GetProcess()->GetTarget().GetArchitecture());

  lldb::RegisterContextSP reg_ctx_sp;

  std::optional<std::string> reg_data = interface.GetRegisterContext();
  if (!reg_data)
    return llvm::createStringError(
        "failed to get scripted frame registers data");

  DataBufferSP data_sp(
      std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));

  if (!data_sp->GetByteSize())
    return llvm::createStringError("failed to copy raw registers data");

  std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
      std::make_shared<RegisterContextMemory>(
          thread, frame_id, *register_info_sp, LLDB_INVALID_ADDRESS);

  reg_ctx_memory->SetAllRegisterData(data_sp);
  reg_ctx_sp = reg_ctx_memory;

  return reg_ctx_sp;
}

lldb::RegisterContextSP ScriptedFrame::GetRegisterContext() {
  if (!m_reg_context_sp) {
    Status error;
    if (!m_scripted_frame_interface_sp)
      return ScriptedInterface::ErrorWithMessage<RegisterContextSP>(
          LLVM_PRETTY_FUNCTION,
          "failed to get scripted frame registers context: invalid interface",
          error, LLDBLog::Thread);

    ThreadSP thread_sp = GetThread();
    if (!thread_sp)
      return ScriptedInterface::ErrorWithMessage<RegisterContextSP>(
          LLVM_PRETTY_FUNCTION,
          "failed to get scripted frame registers context: invalid thread",
          error, LLDBLog::Thread);

    auto regs_or_err = CreateRegisterContext(*m_scripted_frame_interface_sp,
                                             *thread_sp, GetFrameIndex());
    if (!regs_or_err) {
      error = Status::FromError(regs_or_err.takeError());
      return ScriptedInterface::ErrorWithMessage<RegisterContextSP>(
          LLVM_PRETTY_FUNCTION,
          "failed to get scripted frame registers context", error,
          LLDBLog::Thread);
    }

    m_reg_context_sp = *regs_or_err;
  }

  return m_reg_context_sp;
}

VariableList *ScriptedFrame::GetVariableList(bool get_file_globals,
                                             bool include_synthetic_vars,
                                             Status *error_ptr) {
  PopulateVariableListFromInterface(include_synthetic_vars);
  return m_variable_list_sp.get();
}

lldb::VariableListSP
ScriptedFrame::GetInScopeVariableList(bool get_file_globals,
                                      bool include_synthetic_vars,
                                      bool must_have_valid_location) {
  PopulateVariableListFromInterface(include_synthetic_vars);
  return m_variable_list_sp;
}

void ScriptedFrame::PopulateVariableListFromInterface(
    bool include_synthetic_vars) {
  // Fetch values from the interface.
  ValueObjectListSP value_list_sp = GetInterface()->GetVariables();
  if (!value_list_sp)
    return;

  // Convert what we can into a variable.
  m_variable_list_sp = std::make_shared<VariableList>();
  for (uint32_t i = 0, e = value_list_sp->GetSize(); i < e; ++i) {
    ValueObjectSP v = value_list_sp->GetValueObjectAtIndex(i);
    if (!v)
      continue;

    VariableSP var = v->GetVariable();
    if (!var && include_synthetic_vars) {
      // Construct the value type as an synthetic verison of what the value type
      // is. That'll allow the user to tell the scope and the 'synthetic-ness'
      // of the variable.
      lldb::ValueType vt = GetSyntheticValueType(v->GetValueType());

      // Just make up a variable - the frame variable dumper just passes it
      // back in to GetValueObjectForFrameVariable, so we really just need to
      // make sure the name and type are correct. We create IDs based on
      // value_list_sp in order to make sure they're unique.
      var = std::make_shared<lldb_private::Variable>(
          (lldb::user_id_t)value_list_sp->GetSize() + i,
          v->GetName().GetCString(), v->GetName().GetCString(), nullptr, vt,
          /*owner_scope=*/nullptr,
          /*scope_range=*/Variable::RangeList{},
          /*decl=*/nullptr, DWARFExpressionList{}, /*external=*/false,
          /*artificial=*/true, /*location_is_constant_data=*/false);
    }

    // Only append the variable if we have one (had already, or just created).
    if (var)
      m_variable_list_sp->AddVariable(var);
  }
}

lldb::ValueObjectSP ScriptedFrame::GetValueObjectForFrameVariable(
    const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic) {
  // Fetch values from the interface.
  ValueObjectListSP values = m_scripted_frame_interface_sp->GetVariables();
  if (!values)
    return {};

  return values->FindValueObjectByValueName(
      variable_sp->GetName().AsCString(nullptr));
}

lldb::ValueObjectSP ScriptedFrame::FindVariable(ConstString name) {
  // Fetch values from the interface.
  ValueObjectListSP values = m_scripted_frame_interface_sp->GetVariables();
  if (!values)
    return {};

  return values->FindValueObjectByValueName(name.AsCString(nullptr));
}

lldb::ValueObjectSP ScriptedFrame::GetValueForVariableExpressionPath(
    llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic,
    uint32_t options, lldb::VariableSP &var_sp, Status &error,
    lldb::DILMode mode) {
  // Unless the frame implementation knows how to create variables (which it
  // doesn't), we can't construct anything for the variable. This may seem
  // somewhat out of place, but it's basically because of how this API is used -
  // the print command uses this API to fill in var_sp; and this implementation
  // can't do that!
  // FIXME: We should make it possible for the frame implementation to create
  //        Variable objects.
  (void)var_sp;
  // Otherwise, delegate to the scripted frame interface pointer.
  return m_scripted_frame_interface_sp->GetValueObjectForVariableExpression(
      var_expr, options, error);
}
