//===----------------------------------------------------------------------===//
//
// 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/ScriptedThreadPlan.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.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/ValueObject/ValueObjectSynthesizedValue.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();
  lldb::addr_t cfa = scripted_frame_interface->GetCFA();

  SymbolContext sc;
  Address symbol_addr;
  if (pc != LLDB_INVALID_ADDRESS) {
    pc = process_sp->FixCodeAddress(pc);
    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;

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

ScriptedFrame::ScriptedFrame(ThreadSP thread_sp,
                             ScriptedFrameInterfaceSP interface_sp,
                             lldb::user_id_t id, lldb::addr_t pc,
                             lldb::addr_t cfa, SymbolContext &sym_ctx,
                             StructuredData::GenericSP script_object_sp)
    : StackFrame(thread_sp, /*frame_idx=*/id,
                 /*concrete_frame_idx=*/id, /*reg_context_sp=*/nullptr,
                 /*cfa=*/cfa, /*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;

  llvm::Expected<lldb::RegisterContextSP> reg_ctx_or_err =
      CreateRegisterContext();
  if (!reg_ctx_or_err) {
    std::optional<lldb::user_id_t> debugger_id;
    if (ProcessSP process_sp = thread_sp->GetProcess())
      debugger_id = process_sp->GetTarget().GetDebugger().GetID();
    Debugger::ReportError("failed to create scripted frame register context: " +
                              llvm::toString(reg_ctx_or_err.takeError()),
                          debugger_id);
    return;
  }

  m_reg_context_sp = *reg_ctx_or_err;
}

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).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).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;
}

llvm::Expected<DynamicRegisterInfoSP> ScriptedFrame::GetDynamicRegisterInfo() {
  CheckInterpreterAndScriptObject();

  StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();
  if (!reg_info)
    return llvm::createStringError(
        "failed to get scripted frame registers info");

  ThreadSP thread_sp = m_thread_wp.lock();
  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");

  DynamicRegisterInfoSP register_info_sp = DynamicRegisterInfo::Create(
      *reg_info, process_sp->GetTarget().GetArchitecture());
  if (!register_info_sp)
    return llvm::createStringError(
        "failed to create scripted frame registers info");

  return register_info_sp;
}

llvm::Expected<lldb::RegisterContextSP> ScriptedFrame::CreateRegisterContext() {
  if (!m_scripted_frame_interface_sp)
    return llvm::createStringError("invalid scripted frame interface");

  ThreadSP thread_sp = GetThread();
  if (!thread_sp)
    return llvm::createStringError("invalid thread");

  // A frame that reports no register data has no register context. That is a
  // valid state, not a failure: only frames that expose registers implement it.
  std::optional<std::string> reg_data =
      m_scripted_frame_interface_sp->GetRegisterContext();
  if (!reg_data)
    return lldb::RegisterContextSP();

  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");

  llvm::Expected<DynamicRegisterInfoSP> register_info_or_err =
      GetDynamicRegisterInfo();
  if (!register_info_or_err)
    return register_info_or_err.takeError();

  std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
      std::make_shared<RegisterContextMemory>(*thread_sp, GetFrameIndex(),
                                              std::move(*register_info_or_err),
                                              LLDB_INVALID_ADDRESS);

  reg_ctx_memory->SetAllRegisterData(data_sp);

  return reg_ctx_memory;
}

lldb::RegisterContextSP ScriptedFrame::GetRegisterContext() {
  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;

    // Ask the interface about the value type of this variable. If it doesn't
    // specify any, use the original value type.
    lldb::ValueType vt = GetInterface()->GetValueTypeForVariable(v).value_or(
        GetSyntheticValueType(v->GetValueType()));

    if (IsSyntheticValueType(vt) && !include_synthetic_vars)
      continue;

    // 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.
    m_variable_list_sp->AddVariable(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));
  }
}

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 {};

  lldb::ValueObjectSP valobj_sp = values->FindValueObjectByValueName(
      variable_sp->GetName().AsCString(nullptr));
  if (!valobj_sp)
    return {};

  return ValueObjectSynthesizedValue::Create(*valobj_sp,
                                             variable_sp->GetScope());
}

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

  lldb::ValueObjectSP valobj_sp =
      values->FindValueObjectByValueName(name.AsCString(nullptr));
  if (!valobj_sp)
    return {};

  // Present the ValueObject under the same ValueType the frame's variable list
  // would, so reaching a variable by name and by enumeration agree.
  if (m_variable_list_sp) {
    if (VariableSP variable_sp = m_variable_list_sp->FindVariable(name))
      return ValueObjectSynthesizedValue::Create(*valobj_sp,
                                                 variable_sp->GetScope());
  }

  return valobj_sp;
}

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);
}

llvm::Expected<lldb::ThreadPlanSP>
ScriptedFrame::GetThreadPlanForStepType(lldb::StepType step_type) {
  llvm::Expected<ScriptedMetadata> metadata =
      m_scripted_frame_interface_sp->GetThreadPlanMetadataForStepType(
          step_type);
  if (!metadata)
    return metadata.takeError();

  // Returning a ScriptedMetadata with an empty class name means that the
  // scripted frame doesn't know how to step.  That's not an error, but don't
  // try to make a thread plan in this case.  The bool operator of
  // ScriptedMetadata checks the class name...

  ThreadSP thread_sp = GetThread();
  if (thread_sp && !metadata->GetClassName().empty()) {
    lldb::ThreadPlanSP new_plan_sp(
        new ScriptedThreadPlan(*thread_sp.get(), *metadata));
    return new_plan_sp;
  }

  return lldb::ThreadPlanSP();
}
