//===-- Value.h -------------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Value_h_
#define liblldb_Value_h_

#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Scalar.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-private-enumerations.h"
#include "lldb/lldb-private-types.h"

#include "llvm/ADT/APInt.h"

#include <vector>

#include <stdint.h>
#include <string.h>

namespace lldb_private {
class DataExtractor;
class ExecutionContext;
class Module;
class Stream;
class Type;
class Variable;
}

namespace lldb_private {

class Value {
public:
  // Values Less than zero are an error, greater than or equal to zero returns
  // what the Scalar result is.
  enum ValueType {
    // m_value contains...
    // ============================
    eValueTypeScalar,      // raw scalar value
    eValueTypeVector,      // byte array of m_vector.length with endianness of
                           // m_vector.byte_order
    eValueTypeFileAddress, // file address value
    eValueTypeLoadAddress, // load address value
    eValueTypeHostAddress  // host address value (for memory in the process that
                           // is using liblldb)
  };

  enum ContextType // Type that describes Value::m_context
  {
    // m_context contains...
    // ====================
    eContextTypeInvalid,      // undefined
    eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector
                              // register)
    eContextTypeLLDBType,     // lldb_private::Type *
    eContextTypeVariable      // lldb_private::Variable *
  };

  const static size_t kMaxByteSize = 32u;

  struct Vector {
    // The byte array must be big enough to hold vector registers for any
    // supported target.
    uint8_t bytes[kMaxByteSize];
    size_t length;
    lldb::ByteOrder byte_order;

    Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {}

    Vector(const Vector &vector) { *this = vector; }
    const Vector &operator=(const Vector &vector) {
      SetBytes(vector.bytes, vector.length, vector.byte_order);
      return *this;
    }

    void Clear() { length = 0; }

    bool SetBytes(const void *bytes, size_t length,
                  lldb::ByteOrder byte_order) {
      this->length = length;
      this->byte_order = byte_order;
      if (length)
        ::memcpy(this->bytes, bytes,
                 length < kMaxByteSize ? length : kMaxByteSize);
      return IsValid();
    }

    bool IsValid() const {
      return (length > 0 && length < kMaxByteSize &&
              byte_order != lldb::eByteOrderInvalid);
    }
    // Casts a vector, if valid, to an unsigned int of matching or largest
    // supported size. Truncates to the beginning of the vector if required.
    // Returns a default constructed Scalar if the Vector data is internally
    // inconsistent.
    llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
                                  ((type128 *)bytes)->x);
    Scalar GetAsScalar() const {
      Scalar scalar;
      if (IsValid()) {
        if (length == 1)
          scalar = *(const uint8_t *)bytes;
        else if (length == 2)
          scalar = *(const uint16_t *)bytes;
        else if (length == 4)
          scalar = *(const uint32_t *)bytes;
        else if (length == 8)
          scalar = *(const uint64_t *)bytes;
        else if (length >= 16)
          scalar = rhs;
      }
      return scalar;
    }
  };

  Value();
  Value(const Scalar &scalar);
  Value(const Vector &vector);
  Value(const void *bytes, int len);
  Value(const Value &rhs);

  void SetBytes(const void *bytes, int len);

  void AppendBytes(const void *bytes, int len);

  Value &operator=(const Value &rhs);

  const CompilerType &GetCompilerType();

  void SetCompilerType(const CompilerType &compiler_type);

  ValueType GetValueType() const;

  AddressType GetValueAddressType() const;

  ContextType GetContextType() const { return m_context_type; }

  void SetValueType(ValueType value_type) { m_value_type = value_type; }

  void ClearContext() {
    m_context = nullptr;
    m_context_type = eContextTypeInvalid;
  }

  void SetContext(ContextType context_type, void *p) {
    m_context_type = context_type;
    m_context = p;
    if (m_context_type == eContextTypeRegisterInfo) {
      RegisterInfo *reg_info = GetRegisterInfo();
      if (reg_info->encoding == lldb::eEncodingVector &&
          m_vector.byte_order != lldb::eByteOrderInvalid)
        SetValueType(eValueTypeScalar);
    }
  }

  RegisterInfo *GetRegisterInfo() const;

  Type *GetType();

  Scalar &ResolveValue(ExecutionContext *exe_ctx);

  const Scalar &GetScalar() const { return m_value; }

  const Vector &GetVector() const { return m_vector; }

  Scalar &GetScalar() { return m_value; }

  Vector &GetVector() { return m_vector; }

  bool SetVectorBytes(const Vector &vector) {
    m_vector = vector;
    return m_vector.IsValid();
  }

  bool SetVectorBytes(uint8_t *bytes, size_t length,
                      lldb::ByteOrder byte_order) {
    return m_vector.SetBytes(bytes, length, byte_order);
  }

  bool SetScalarFromVector() {
    if (m_vector.IsValid()) {
      m_value = m_vector.GetAsScalar();
      return true;
    }
    return false;
  }

  size_t ResizeData(size_t len);

  size_t AppendDataToHostBuffer(const Value &rhs);

  DataBufferHeap &GetBuffer() { return m_data_buffer; }

  const DataBufferHeap &GetBuffer() const { return m_data_buffer; }

  bool ValueOf(ExecutionContext *exe_ctx);

  Variable *GetVariable();

  void Dump(Stream *strm);

  lldb::Format GetValueDefaultFormat();

  uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx);

  Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
                        uint32_t data_offset,
                        Module *module); // Can be nullptr

  static const char *GetValueTypeAsCString(ValueType context_type);

  static const char *GetContextTypeAsCString(ContextType context_type);

  /// Convert this value's file address to a load address, if possible.
  void ConvertToLoadAddress(Module *module, Target *target);

  bool GetData(DataExtractor &data);

  void Clear();

protected:
  Scalar m_value;
  Vector m_vector;
  CompilerType m_compiler_type;
  void *m_context;
  ValueType m_value_type;
  ContextType m_context_type;
  DataBufferHeap m_data_buffer;
};

class ValueList {
public:
  ValueList() : m_values() {}

  ValueList(const ValueList &rhs);

  ~ValueList() = default;

  const ValueList &operator=(const ValueList &rhs);

  // void InsertValue (Value *value, size_t idx);
  void PushValue(const Value &value);

  size_t GetSize();
  Value *GetValueAtIndex(size_t idx);
  void Clear();

private:
  typedef std::vector<Value> collection;

  collection m_values;
};

} // namespace lldb_private

#endif // liblldb_Value_h_
