//===-- Value.h -------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_Value_h_
#define liblldb_Value_h_

#include "lldb/Core/Scalar.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"         // for ByteOrder, ByteOrder::eB...
#include "lldb/lldb-private-enumerations.h" // for AddressType
#include "lldb/lldb-private-types.h"        // for type128, RegisterInfo

#include "llvm/ADT/APInt.h" // for APInt

#include <vector>

#include <stdint.h> // for uint8_t, uint32_t, uint64_t
#include <string.h> // for size_t, memcpy

namespace lldb_private {
class DataExtractor;
}
namespace lldb_private {
class ExecutionContext;
}
namespace lldb_private {
class Module;
}
namespace lldb_private {
class Stream;
}
namespace lldb_private {
class Type;
}
namespace lldb_private {
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_
