//===-- ValueObjectMemory.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/ValueObject/ValueObjectMemory.h"
#include "lldb/Core/Value.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/lldb-types.h"
#include "llvm/Support/ErrorHandling.h"

#include <cassert>
#include <memory>
#include <optional>

namespace lldb_private {
class ExecutionContextScope;
}

using namespace lldb;
using namespace lldb_private;

ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope,
                                        llvm::StringRef name,
                                        const Address &address,
                                        lldb::TypeSP &type_sp,
                                        ValueObject *parent) {

  std::shared_ptr<ValueObjectManager> manager_sp =
      ValueObject::ReuseManagerIfParent(parent);
  return (new ValueObjectMemory(exe_scope, *manager_sp, name, address, type_sp))
      ->GetSP();
}

ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope,
                                        llvm::StringRef name,
                                        const Address &address,
                                        const CompilerType &ast_type,
                                        ValueObject *parent) {
  std::shared_ptr<ValueObjectManager> manager_sp =
      ValueObject::ReuseManagerIfParent(parent);
  return (new ValueObjectMemory(exe_scope, *manager_sp, name, address,
                                ast_type))
      ->GetSP();
}

ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope,
                                     ValueObjectManager &manager,
                                     llvm::StringRef name,
                                     const Address &address,
                                     lldb::TypeSP &type_sp)
    : ValueObject(exe_scope, manager), m_address(address), m_type_sp(type_sp),
      m_compiler_type() {
  // Do not attempt to construct one of these objects with no variable!
  assert(m_type_sp.get() != nullptr);
  SetName(name);
  m_value.SetContext(Value::ContextType::LLDBType, m_type_sp.get());
  TargetSP target_sp(GetTargetSP());
  lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
  if (load_address != LLDB_INVALID_ADDRESS) {
    m_value.SetValueType(Value::ValueType::LoadAddress);
    m_value.GetScalar() = load_address;
  } else {
    lldb::addr_t file_address = m_address.GetFileAddress();
    if (file_address != LLDB_INVALID_ADDRESS) {
      m_value.SetValueType(Value::ValueType::FileAddress);
      m_value.GetScalar() = file_address;
    } else {
      m_value.GetScalar() = m_address.GetOffset();
      m_value.SetValueType(Value::ValueType::Scalar);
    }
  }
}

ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope,
                                     ValueObjectManager &manager,
                                     llvm::StringRef name,
                                     const Address &address,
                                     const CompilerType &ast_type)
    : ValueObject(exe_scope, manager), m_address(address), m_type_sp(),
      m_compiler_type(ast_type) {
  // Do not attempt to construct one of these objects with no variable!
  assert(m_compiler_type.IsValid());

  TargetSP target_sp(GetTargetSP());

  SetName(name);
  m_value.SetCompilerType(m_compiler_type);
  lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
  if (load_address != LLDB_INVALID_ADDRESS) {
    m_value.SetValueType(Value::ValueType::LoadAddress);
    m_value.GetScalar() = load_address;
  } else {
    lldb::addr_t file_address = m_address.GetFileAddress();
    if (file_address != LLDB_INVALID_ADDRESS) {
      m_value.SetValueType(Value::ValueType::FileAddress);
      m_value.GetScalar() = file_address;
    } else {
      m_value.GetScalar() = m_address.GetOffset();
      m_value.SetValueType(Value::ValueType::Scalar);
    }
  }
}

ValueObjectMemory::~ValueObjectMemory() = default;

CompilerType ValueObjectMemory::GetCompilerTypeImpl() {
  if (m_type_sp)
    return m_type_sp->GetForwardCompilerType();
  return m_compiler_type;
}

ConstString ValueObjectMemory::GetTypeName() {
  if (m_type_sp)
    return m_type_sp->GetName();
  return m_compiler_type.GetTypeName();
}

ConstString ValueObjectMemory::GetDisplayTypeName() {
  if (m_type_sp)
    return m_type_sp->GetForwardCompilerType().GetDisplayTypeName();
  return m_compiler_type.GetDisplayTypeName();
}

llvm::Expected<uint32_t> ValueObjectMemory::CalculateNumChildren(uint32_t max) {
  if (m_type_sp) {
    auto child_count = m_type_sp->GetNumChildren(true);
    if (!child_count)
      return child_count;
    return *child_count <= max ? *child_count : max;
  }

  ExecutionContext exe_ctx(GetExecutionContextRef());
  const bool omit_empty_base_classes = true;
  auto child_count =
      m_compiler_type.GetNumChildren(omit_empty_base_classes, &exe_ctx);
  if (!child_count)
    return child_count;
  return *child_count <= max ? *child_count : max;
}

llvm::Expected<uint64_t> ValueObjectMemory::GetByteSize() {
  ExecutionContext exe_ctx(GetExecutionContextRef());
  if (m_type_sp) {
    if (auto size =
            m_type_sp->GetByteSize(exe_ctx.GetBestExecutionContextScope()))
      return *size;
    else
      LLDB_LOG_ERROR(GetLog(LLDBLog::Types), size.takeError(),
                     "failed to get byte size from type: {0}");
    return llvm::createStringError("could not get byte size of memory object");
  }
  return m_compiler_type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
}

lldb::ValueType ValueObjectMemory::GetValueType() const {
  // RETHINK: Should this be inherited from somewhere?
  return lldb::eValueTypeVariableGlobal;
}

bool ValueObjectMemory::UpdateValue() {
  SetValueIsValid(false);
  m_error.Clear();

  ExecutionContext exe_ctx(GetExecutionContextRef());

  Target *target = exe_ctx.GetTargetPtr();
  if (target) {
    m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
    m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
  }

  Value old_value(m_value);
  if (m_address.IsValid()) {
    Value::ValueType value_type = m_value.GetValueType();

    switch (value_type) {
    case Value::ValueType::Invalid:
      m_error = Status::FromErrorString("Invalid value");
      return false;
    case Value::ValueType::Scalar:
      // The variable value is in the Scalar value inside the m_value. We can
      // point our m_data right to it.
      m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
      break;

    case Value::ValueType::FileAddress:
    case Value::ValueType::LoadAddress:
    case Value::ValueType::HostAddress:
      // The DWARF expression result was an address in the inferior process. If
      // this variable is an aggregate type, we just need the address as the
      // main value as all child variable objects will rely upon this location
      // and add an offset and then read their own values as needed. If this
      // variable is a simple type, we read all data for it into m_data. Make
      // sure this type has a value before we try and read it

      // If we have a file address, convert it to a load address if we can.
      if (value_type == Value::ValueType::FileAddress &&
          exe_ctx.GetProcessPtr()) {
        lldb::addr_t load_addr = m_address.GetLoadAddress(target);
        if (load_addr != LLDB_INVALID_ADDRESS) {
          m_value.SetValueType(Value::ValueType::LoadAddress);
          m_value.GetScalar() = load_addr;
        }
      }

      if (!CanProvideValue()) {
        // this value object represents an aggregate type whose children have
        // values, but this object does not. So we say we are changed if our
        // location has changed.
        SetValueDidChange(value_type != old_value.GetValueType() ||
                          m_value.GetScalar() != old_value.GetScalar());
      } else {
        // Copy the Value and set the context to use our Variable so it can
        // extract read its value into m_data appropriately
        Value value(m_value);
        if (m_type_sp)
          value.SetContext(Value::ContextType::LLDBType, m_type_sp.get());
        else {
          value.SetCompilerType(m_compiler_type);
        }

        m_error = value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
      }
      break;
    }

    SetValueIsValid(m_error.Success());
  }
  return m_error.Success();
}

bool ValueObjectMemory::IsInScope() {
  // FIXME: Maybe try to read the memory address, and if that works, then
  // we are in scope?
  return true;
}

lldb::ModuleSP ValueObjectMemory::GetModule() { return m_address.GetModule(); }
