/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "PdxInstanceImpl.hpp"

#include <algorithm>

#include <geode/Cache.hpp>
#include <geode/PdxFieldTypes.hpp>
#include <geode/PdxReader.hpp>
#include <geode/internal/DataSerializablePrimitive.hpp>

#include "CacheRegionHelper.hpp"
#include "DataInputInternal.hpp"
#include "PdxHelper.hpp"
#include "Utils.hpp"
#include "util/string.hpp"

namespace {

int8_t BOOLEAN_DEFAULT_BYTES[] = {0};
int8_t BYTE_DEFAULT_BYTES[] = {0};
int8_t SHORT_DEFAULT_BYTES[] = {0, 0};
int8_t CHAR_DEFAULT_BYTES[] = {0, 0};
int8_t INT_DEFAULT_BYTES[] = {0, 0, 0, 0};
int8_t LONG_DEFAULT_BYTES[] = {0, 0, 0, 0, 0, 0, 0, 0};
int8_t FLOAT_DEFAULT_BYTES[] = {0, 0, 0, 0};
int8_t DOUBLE_DEFAULT_BYTES[] = {0, 0, 0, 0, 0, 0, 0, 0};
int8_t DATE_DEFAULT_BYTES[] = {-1, -1, -1, -1, -1, -1, -1, -1};
int8_t STRING_DEFAULT_BYTES[] = {
    static_cast<int8_t>(apache::geode::client::DSCode::CacheableNullString)};
int8_t OBJECT_DEFAULT_BYTES[] = {
    static_cast<int8_t>(apache::geode::client::DSCode::NullObj)};
int8_t NULL_ARRAY_DEFAULT_BYTES[] = {-1};
std::shared_ptr<apache::geode::client::PdxFieldType> DEFAULT_PDX_FIELD_TYPE(
    new apache::geode::client::PdxFieldType(
        "default", "default", apache::geode::client::PdxFieldTypes::UNKNOWN,
        -1 /*field index*/, false, 1, -1 /*var len field idx*/));
}  // namespace

namespace apache {
namespace geode {
namespace client {

using internal::DataSerializablePrimitive;

PdxInstanceImpl::~PdxInstanceImpl() noexcept {}

PdxInstanceImpl::PdxInstanceImpl(const uint8_t* buffer, size_t length,
                                 std::shared_ptr<PdxType> pdxType,
                                 CachePerfStats& cacheStats,
                                 PdxTypeRegistry& pdxTypeRegistry,
                                 const CacheImpl& cacheImpl,
                                 bool enableTimeStatistics)
    : buffer_(buffer, buffer + length),
      typeId_(pdxType->getTypeId()),
      pdxType_(pdxType),
      cacheStats_(cacheStats),
      pdxTypeRegistry_(pdxTypeRegistry),
      cacheImpl_(cacheImpl),
      enableTimeStatistics_(enableTimeStatistics) {
  cacheStats.incPdxInstanceCreations();
  LOGDEBUG("PdxInstanceImpl::m_bufferLength = %zu ", buffer_.size());
}

PdxInstanceImpl::PdxInstanceImpl(FieldVsValues fieldVsValue,
                                 std::shared_ptr<PdxType> pdxType,
                                 CachePerfStats& cacheStats,
                                 PdxTypeRegistry& pdxTypeRegistry,
                                 const CacheImpl& cacheImpl,
                                 bool enableTimeStatistics)
    : typeId_(0),
      pdxType_(pdxType),
      m_updatedFields(fieldVsValue),
      cacheStats_(cacheStats),
      pdxTypeRegistry_(pdxTypeRegistry),
      cacheImpl_(cacheImpl),
      enableTimeStatistics_(enableTimeStatistics) {
  cacheStats.incPdxInstanceCreations();
  pdxType_->InitializeType();  // to generate static position map
}

void PdxInstanceImpl::writeField(PdxWriter& writer, const std::string& name,
                                 PdxFieldTypes typeId,
                                 std::shared_ptr<Cacheable> value) {
  switch (typeId) {
    case PdxFieldTypes::INT: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableInt32>(value)) {
        writer.writeInt(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::STRING: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableString>(value)) {
        writer.writeString(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::BOOLEAN: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableBoolean>(value)) {
        writer.writeBoolean(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::FLOAT: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableFloat>(value)) {
        writer.writeFloat(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::DOUBLE: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableDouble>(value)) {
        writer.writeDouble(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::CHAR: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableCharacter>(value)) {
        writer.writeChar(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::BYTE: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableByte>(value)) {
        writer.writeByte(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::SHORT: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableInt16>(value)) {
        writer.writeShort(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::LONG: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableInt64>(value)) {
        writer.writeLong(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::BYTE_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableBytes>(value)) {
        writer.writeByteArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::DOUBLE_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableDoubleArray>(value)) {
        writer.writeDoubleArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::FLOAT_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableFloatArray>(value)) {
        writer.writeFloatArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::SHORT_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableInt16Array>(value)) {
        writer.writeShortArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::INT_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableInt32Array>(value)) {
        writer.writeIntArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::LONG_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableInt64Array>(value)) {
        writer.writeLongArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::BOOLEAN_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<BooleanArray>(value)) {
        writer.writeBooleanArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::CHAR_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CharArray>(value)) {
        writer.writeCharArray(name, val->value());
      }
      break;
    }
    case PdxFieldTypes::STRING_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableStringArray>(value)) {
        auto size = val->length();
        std::vector<std::string> strings;
        strings.reserve(size);
        for (int item = 0; item < size; item++) {
          strings.push_back((*val)[item]->value());
        }
        writer.writeStringArray(name, strings);
      }
      break;
    }
    case PdxFieldTypes::DATE: {
      if (auto&& date = std::dynamic_pointer_cast<CacheableDate>(value)) {
        writer.writeDate(name, date);
      }
      break;
    }
    case PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS: {
      if (auto&& vector = std::dynamic_pointer_cast<CacheableVector>(value)) {
        const auto size = vector->size();
        int8_t** values = new int8_t*[size];
        auto lengths = new int[size];
        size_t i = 0;
        for (auto&& entry : *vector) {
          if (auto&& val = std::dynamic_pointer_cast<CacheableBytes>(entry)) {
            values[i] = const_cast<int8_t*>(
                reinterpret_cast<const int8_t*>(val->value().data()));
            lengths[i] = val->length();
          }
          i++;
        }
        writer.writeArrayOfByteArrays(name, values, static_cast<int>(size),
                                      lengths);
        delete[] values;
        delete[] lengths;
      }
      break;
    }
    case PdxFieldTypes::OBJECT_ARRAY: {
      if (auto&& val = std::dynamic_pointer_cast<CacheableObjectArray>(value)) {
        writer.writeObjectArray(name, val);
      }
      break;
    }
    case PdxFieldTypes::UNKNOWN:
    case PdxFieldTypes::OBJECT: {
      writer.writeObject(name, value);
    }
  }
}
std::shared_ptr<WritablePdxInstance> PdxInstanceImpl::createWriter() {
  LOGDEBUG("PdxInstanceImpl::createWriter m_bufferLength = %zu m_typeId = %d ",
           buffer_.size(), typeId_);
  const auto& stream = getPdxStream();
  return std::make_shared<PdxInstanceImpl>(
      stream.data(), stream.size(), pdxType_, cacheStats_, pdxTypeRegistry_,
      cacheImpl_,
      enableTimeStatistics_);  // need to create duplicate byte stream);
}

bool PdxInstanceImpl::enumerateObjectArrayEquals(
    std::shared_ptr<CacheableObjectArray> Obj,
    std::shared_ptr<CacheableObjectArray> OtherObj) {
  if (Obj == nullptr && OtherObj == nullptr) {
    return true;
  } else if (Obj == nullptr && OtherObj != nullptr) {
    return false;
  } else if (Obj != nullptr && OtherObj == nullptr) {
    return false;
  }

  if (Obj->size() != OtherObj->size()) {
    return false;
  }

  for (size_t i = 0; i < Obj->size(); i++) {
    if (!deepArrayEquals(Obj->at(i), OtherObj->at(i))) {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::enumerateVectorEquals(
    std::shared_ptr<CacheableVector> Obj,
    std::shared_ptr<CacheableVector> OtherObj) {
  if (Obj == nullptr && OtherObj == nullptr) {
    return true;
  } else if (Obj == nullptr && OtherObj != nullptr) {
    return false;
  } else if (Obj != nullptr && OtherObj == nullptr) {
    return false;
  }

  if (Obj->size() != OtherObj->size()) {
    return false;
  }

  for (size_t i = 0; i < Obj->size(); i++) {
    if (!deepArrayEquals(Obj->at(i), OtherObj->at(i))) {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::enumerateArrayListEquals(
    std::shared_ptr<CacheableArrayList> Obj,
    std::shared_ptr<CacheableArrayList> OtherObj) {
  if (Obj == nullptr && OtherObj == nullptr) {
    return true;
  } else if (Obj == nullptr && OtherObj != nullptr) {
    return false;
  } else if (Obj != nullptr && OtherObj == nullptr) {
    return false;
  }

  if (Obj->size() != OtherObj->size()) {
    return false;
  }

  for (size_t i = 0; i < Obj->size(); i++) {
    if (!deepArrayEquals(Obj->at(i), OtherObj->at(i))) {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::enumerateMapEquals(
    std::shared_ptr<CacheableHashMap> Obj,
    std::shared_ptr<CacheableHashMap> OtherObj) {
  if (Obj == nullptr && OtherObj == nullptr) {
    return true;
  } else if (Obj == nullptr && OtherObj != nullptr) {
    return false;
  } else if (Obj != nullptr && OtherObj == nullptr) {
    return false;
  }

  if (Obj->size() != OtherObj->size()) {
    return false;
  }

  for (const auto& iter : *Obj) {
    const auto& otherIter = OtherObj->find(iter.first);
    if (otherIter != OtherObj->end()) {
      if (!deepArrayEquals(iter.second, otherIter->second)) {
        return false;
      }
    } else {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::enumerateHashTableEquals(
    std::shared_ptr<CacheableHashTable> Obj,
    std::shared_ptr<CacheableHashTable> OtherObj) {
  if (Obj == nullptr && OtherObj == nullptr) {
    return true;
  } else if (Obj == nullptr && OtherObj != nullptr) {
    return false;
  } else if (Obj != nullptr && OtherObj == nullptr) {
    return false;
  }

  if (Obj->size() != OtherObj->size()) {
    return false;
  }

  for (const auto& iter : *Obj) {
    const auto& otherIter = OtherObj->find(iter.first);
    if (otherIter != OtherObj->end()) {
      if (!deepArrayEquals(iter.second, otherIter->second)) {
        return false;
      }
    } else {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::enumerateSetEquals(
    std::shared_ptr<CacheableHashSet> Obj,
    std::shared_ptr<CacheableHashSet> OtherObj) {
  if (Obj == nullptr && OtherObj == nullptr) {
    return true;
  } else if (Obj == nullptr && OtherObj != nullptr) {
    return false;
  } else if (Obj != nullptr && OtherObj == nullptr) {
    return false;
  }

  if (Obj->size() != OtherObj->size()) {
    return false;
  }
  for (const auto& iter : *Obj) {
    if (OtherObj->find(iter) == OtherObj->end()) {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::enumerateLinkedSetEquals(
    std::shared_ptr<CacheableLinkedHashSet> Obj,
    std::shared_ptr<CacheableLinkedHashSet> OtherObj) {
  if (Obj == nullptr && OtherObj == nullptr) {
    return true;
  } else if (Obj == nullptr && OtherObj != nullptr) {
    return false;
  } else if (Obj != nullptr && OtherObj == nullptr) {
    return false;
  }

  if (Obj->size() != OtherObj->size()) {
    return false;
  }
  for (const auto& iter : *Obj) {
    if (OtherObj->find(iter) == OtherObj->end()) {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::deepArrayEquals(std::shared_ptr<Cacheable> obj,
                                      std::shared_ptr<Cacheable> otherObj) {
  if (obj == nullptr && otherObj == nullptr) {
    return true;
  } else if (obj == nullptr && otherObj != nullptr) {
    return false;
  } else if (obj != nullptr && otherObj == nullptr) {
    return false;
  }

  if (auto primitive =
          std::dynamic_pointer_cast<DataSerializablePrimitive>(obj)) {
    switch (primitive->getDsCode()) {
      case DSCode::CacheableObjectArray: {
        auto objArrayPtr = std::dynamic_pointer_cast<CacheableObjectArray>(obj);
        auto otherObjArrayPtr =
            std::dynamic_pointer_cast<CacheableObjectArray>(otherObj);
        return enumerateObjectArrayEquals(objArrayPtr, otherObjArrayPtr);
      }
      case DSCode::CacheableVector: {
        auto vec = std::dynamic_pointer_cast<CacheableVector>(obj);
        auto otherVec = std::dynamic_pointer_cast<CacheableVector>(otherObj);
        return enumerateVectorEquals(vec, otherVec);
      }
      case DSCode::CacheableArrayList: {
        auto arrList = std::dynamic_pointer_cast<CacheableArrayList>(obj);
        auto otherArrList =
            std::dynamic_pointer_cast<CacheableArrayList>(otherObj);
        return enumerateArrayListEquals(arrList, otherArrList);
      }
      case DSCode::CacheableHashMap: {
        auto map = std::dynamic_pointer_cast<CacheableHashMap>(obj);
        auto otherMap = std::dynamic_pointer_cast<CacheableHashMap>(otherObj);
        return enumerateMapEquals(map, otherMap);
      }
      case DSCode::CacheableHashSet: {
        auto hashset = std::dynamic_pointer_cast<CacheableHashSet>(obj);
        auto otherHashset =
            std::dynamic_pointer_cast<CacheableHashSet>(otherObj);
        return enumerateSetEquals(hashset, otherHashset);
      }
      case DSCode::CacheableLinkedHashSet: {
        auto linkedHashset =
            std::dynamic_pointer_cast<CacheableLinkedHashSet>(obj);
        auto otherLinkedHashset =
            std::dynamic_pointer_cast<CacheableLinkedHashSet>(otherObj);
        return enumerateLinkedSetEquals(linkedHashset, otherLinkedHashset);
      }
      case DSCode::CacheableHashTable: {
        auto hashTable = std::dynamic_pointer_cast<CacheableHashTable>(obj);
        auto otherhashTable =
            std::dynamic_pointer_cast<CacheableHashTable>(otherObj);
        return enumerateHashTableEquals(hashTable, otherhashTable);
      }
      case DSCode::FixedIDDefault:
      case DSCode::FixedIDByte:
      case DSCode::FixedIDShort:
      case DSCode::FixedIDInt:
      case DSCode::FixedIDNone:
      case DSCode::CacheableLinkedList:
      case DSCode::Properties:
      case DSCode::PdxType:
      case DSCode::BooleanArray:
      case DSCode::CharArray:
      case DSCode::CacheableUserData:
      case DSCode::CacheableUserData2:
      case DSCode::CacheableUserData4:
      case DSCode::NullObj:
      case DSCode::Class:
      case DSCode::JavaSerializable:
      case DSCode::DataSerializable:
      case DSCode::CacheableBytes:
      case DSCode::CacheableInt16Array:
      case DSCode::CacheableInt32Array:
      case DSCode::CacheableInt64Array:
      case DSCode::CacheableFloatArray:
      case DSCode::CacheableDoubleArray:
      case DSCode::CacheableBoolean:
      case DSCode::CacheableCharacter:
      case DSCode::CacheableByte:
      case DSCode::CacheableInt16:
      case DSCode::CacheableInt32:
      case DSCode::CacheableInt64:
      case DSCode::CacheableFloat:
      case DSCode::CacheableDouble:
      case DSCode::CacheableDate:
      case DSCode::CacheableFileName:
      case DSCode::CacheableStringArray:
      case DSCode::CacheableTimeUnit:
      case DSCode::CacheableIdentityHashMap:
      case DSCode::CacheableStack:
      case DSCode::PDX:
      case DSCode::PDX_ENUM:
      case DSCode::CacheableString:
      case DSCode::CacheableNullString:
      case DSCode::CacheableASCIIString:
      case DSCode::CacheableASCIIStringHuge:
      case DSCode::CacheableStringHuge:
        break;
    }
  }

  if (auto pdxInstance = std::dynamic_pointer_cast<PdxInstance>(obj)) {
    if (auto otherPdxInstance =
            std::dynamic_pointer_cast<PdxInstance>(otherObj)) {
      return *pdxInstance == *otherPdxInstance;
    }
  }

  if (auto keyType = std::dynamic_pointer_cast<CacheableKey>(obj)) {
    if (auto otherKeyType = std::dynamic_pointer_cast<CacheableKey>(otherObj)) {
      return *keyType == *otherKeyType;
    }
  }

  throw IllegalStateException(
      "PdxInstance cannot calculate equals of the field " + obj->toString() +
      " since equals is only supported for CacheableKey derived types.");
}

int PdxInstanceImpl::enumerateMapHashCode(
    std::shared_ptr<CacheableHashMap> map) {
  int h = 0;
  for (const auto& itr : *map) {
    h = h + ((deepArrayHashCode(itr.first)) ^
             ((itr.second) ? deepArrayHashCode(itr.second) : 0));
  }
  return h;
}

int PdxInstanceImpl::enumerateSetHashCode(
    std::shared_ptr<CacheableHashSet> set) {
  int h = 0;
  for (const auto& itr : *set) {
    h = h + deepArrayHashCode(itr);
  }
  return h;
}

int PdxInstanceImpl::enumerateLinkedSetHashCode(
    std::shared_ptr<CacheableLinkedHashSet> set) {
  int h = 0;
  for (const auto& itr : *set) {
    h = h + deepArrayHashCode(itr);
  }
  return h;
}

int PdxInstanceImpl::enumerateHashTableCode(
    std::shared_ptr<CacheableHashTable> hashTable) {
  int h = 0;
  for (const auto& itr : *hashTable) {
    h = h + ((deepArrayHashCode(itr.first)) ^
             ((itr.second) ? deepArrayHashCode(itr.second) : 0));
  }
  return h;
}

int PdxInstanceImpl::enumerateObjectArrayHashCode(
    std::shared_ptr<CacheableObjectArray> objArray) {
  int h = 1;
  for (const auto& obj : *objArray) {
    h = h * 31 + deepArrayHashCode(obj);
  }
  return h;
}

int PdxInstanceImpl::enumerateVectorHashCode(
    std::shared_ptr<CacheableVector> vec) {
  int h = 1;
  for (const auto& obj : *vec) {
    h = h * 31 + deepArrayHashCode(obj);
  }
  return h;
}

int PdxInstanceImpl::enumerateArrayListHashCode(
    std::shared_ptr<CacheableArrayList> arrList) {
  int h = 1;
  for (const auto& obj : *arrList) {
    h = h * 31 + deepArrayHashCode(obj);
  }
  return h;
}

int PdxInstanceImpl::enumerateLinkedListHashCode(
    std::shared_ptr<CacheableLinkedList> linkedList) {
  int h = 1;
  for (const auto& obj : *linkedList) {
    h = h * 31 + deepArrayHashCode(obj);
  }
  return h;
}

int PdxInstanceImpl::deepArrayHashCode(std::shared_ptr<Cacheable> obj) {
  if (obj == nullptr) {
    return 0;
  }

  if (auto primitive =
          std::dynamic_pointer_cast<DataSerializablePrimitive>(obj)) {
    switch (primitive->getDsCode()) {
      case DSCode::CacheableObjectArray: {
        return enumerateObjectArrayHashCode(
            std::dynamic_pointer_cast<CacheableObjectArray>(obj));
      }
      case DSCode::CacheableVector: {
        return enumerateVectorHashCode(
            std::dynamic_pointer_cast<CacheableVector>(obj));
      }
      case DSCode::CacheableArrayList: {
        return enumerateArrayListHashCode(
            std::dynamic_pointer_cast<CacheableArrayList>(obj));
      }
      case DSCode::CacheableLinkedList: {
        return enumerateLinkedListHashCode(
            std::dynamic_pointer_cast<CacheableLinkedList>(obj));
      }
      case DSCode::CacheableHashMap: {
        return enumerateMapHashCode(
            std::dynamic_pointer_cast<CacheableHashMap>(obj));
      }
      case DSCode::CacheableHashSet: {
        return enumerateSetHashCode(
            std::dynamic_pointer_cast<CacheableHashSet>(obj));
      }
      case DSCode::CacheableLinkedHashSet: {
        auto linkedHashSet =
            std::dynamic_pointer_cast<CacheableLinkedHashSet>(obj);
        return enumerateLinkedSetHashCode(linkedHashSet);
      }
      case DSCode::CacheableHashTable: {
        return enumerateHashTableCode(
            std::dynamic_pointer_cast<CacheableHashTable>(obj));
      }
      case DSCode::FixedIDDefault:
      case DSCode::FixedIDByte:
      case DSCode::FixedIDInt:
      case DSCode::FixedIDNone:
      case DSCode::FixedIDShort:
      case DSCode::Properties:
      case DSCode::PdxType:
      case DSCode::BooleanArray:
      case DSCode::CharArray:
      case DSCode::NullObj:
      case DSCode::CacheableString:
      case DSCode::Class:
      case DSCode::JavaSerializable:
      case DSCode::DataSerializable:
      case DSCode::CacheableBytes:
      case DSCode::CacheableInt16Array:
      case DSCode::CacheableInt32Array:
      case DSCode::CacheableInt64Array:
      case DSCode::CacheableFloatArray:
      case DSCode::CacheableDoubleArray:
      case DSCode::CacheableBoolean:
      case DSCode::CacheableCharacter:
      case DSCode::CacheableByte:
      case DSCode::CacheableInt16:
      case DSCode::CacheableInt32:
      case DSCode::CacheableInt64:
      case DSCode::CacheableFloat:
      case DSCode::CacheableDouble:
      case DSCode::CacheableDate:
      case DSCode::CacheableFileName:
      case DSCode::CacheableStringArray:
      case DSCode::CacheableTimeUnit:
      case DSCode::CacheableNullString:
      case DSCode::CacheableIdentityHashMap:
      case DSCode::CacheableStack:
      case DSCode::CacheableASCIIString:
      case DSCode::CacheableASCIIStringHuge:
      case DSCode::CacheableStringHuge:
      case DSCode::CacheableUserData:
      case DSCode::CacheableUserData2:
      case DSCode::CacheableUserData4:
      case DSCode::PDX:
      case DSCode::PDX_ENUM:
        break;
    }
  }

  if (auto pdxInstance = std::dynamic_pointer_cast<PdxInstance>(obj)) {
    return pdxInstance->hashcode();
  }

  if (auto keyType = std::dynamic_pointer_cast<CacheableKey>(obj)) {
    return keyType->hashcode();
  }

  throw IllegalStateException(
      "PdxInstance cannot calculate hashcode of the field " + obj->toString() +
      " since equals is only supported for CacheableKey derived types.");
}

int32_t PdxInstanceImpl::hashcode() const {
  const auto& stream = getPdxStream();
  auto input = cacheImpl_.createDataInput(stream.data(), stream.size());

  int hashCode = 1;
  for (const auto& field : getIdentityPdxFields()) {
    LOGDEBUG("hashcode for pdxfield %s  hashcode is %d ",
             field->getFieldName().c_str(), hashCode);
    switch (field->getTypeId()) {
      case PdxFieldTypes::CHAR:
      case PdxFieldTypes::BOOLEAN:
      case PdxFieldTypes::BYTE:
      case PdxFieldTypes::SHORT:
      case PdxFieldTypes::INT:
      case PdxFieldTypes::LONG:
      case PdxFieldTypes::DATE:
      case PdxFieldTypes::FLOAT:
      case PdxFieldTypes::DOUBLE:
      case PdxFieldTypes::STRING:
      case PdxFieldTypes::BOOLEAN_ARRAY:
      case PdxFieldTypes::CHAR_ARRAY:
      case PdxFieldTypes::BYTE_ARRAY:
      case PdxFieldTypes::SHORT_ARRAY:
      case PdxFieldTypes::INT_ARRAY:
      case PdxFieldTypes::LONG_ARRAY:
      case PdxFieldTypes::FLOAT_ARRAY:
      case PdxFieldTypes::DOUBLE_ARRAY:
      case PdxFieldTypes::STRING_ARRAY:
      case PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS: {
        int retH = getRawHashCode(input, field);
        if (retH != 0) {
          hashCode = 31 * hashCode + retH;
        }
        break;
      }
      case PdxFieldTypes::OBJECT: {
        setOffsetForObject(input, field->getSequenceId());
        std::shared_ptr<Cacheable> object = nullptr;
        input.readObject(object);
        if (object != nullptr) {
          hashCode = 31 * hashCode + deepArrayHashCode(object);
        }
        break;
      }
      case PdxFieldTypes::OBJECT_ARRAY: {
        setOffsetForObject(input, field->getSequenceId());
        auto objectArray = CacheableObjectArray::create();
        objectArray->fromData(input);
        hashCode =
            31 * hashCode +
            ((objectArray != nullptr) ? deepArrayHashCode(objectArray) : 0);
        break;
      }
      case PdxFieldTypes::UNKNOWN: {
        throw IllegalStateException(
            "PdxInstance not found typeid " +
            std::to_string(static_cast<int>(field->getTypeId())));
      }
    }
  }

  return hashCode;
}

int PdxInstanceImpl::getTypeId() const { return typeId_; }

std::shared_ptr<PdxType> PdxInstanceImpl::getPdxType(Pool* pool) const {
  auto registry = cacheImpl_.getPdxTypeRegistry();
  auto type = registry->getPdxType(typeId_);
  if (type != nullptr) {
    return type;
  }

  auto id = registry->getPDXIdForType(pdxType_, pool);
  pdxType_->setTypeId(id);
  typeId_ = id;

  return pdxType_;
}

void PdxInstanceImpl::updatePdxStream(std::vector<uint8_t> stream) {
  buffer_ = std::move(stream);
}

const std::vector<uint8_t>& PdxInstanceImpl::getPdxStream() const {
  if (buffer_.empty()) {
    auto output = cacheImpl_.createDataOutput();
    PdxLocalWriter plw{output, pdxType_, cacheImpl_.getPdxTypeRegistry()};

    toData(plw);
    plw.endObjectWriting();
    buffer_ = plw.getPdxStream();
  }

  return buffer_;
}

bool PdxInstanceImpl::isIdentityField(const std::string& name) {
  auto field = pdxType_->getPdxField(name);
  return field != nullptr && field->getIdentityField();
}

bool PdxInstanceImpl::hasField(const std::string& name) {
  return pdxType_->getPdxField(name) != nullptr;
}

bool PdxInstanceImpl::getBooleanField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readBoolean();
}

int8_t PdxInstanceImpl::getByteField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.read();
}

int16_t PdxInstanceImpl::getShortField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readInt16();
}

int32_t PdxInstanceImpl::getIntField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readInt32();
}

int64_t PdxInstanceImpl::getLongField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readInt64();
}

float PdxInstanceImpl::getFloatField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readFloat();
}

double PdxInstanceImpl::getDoubleField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readDouble();
}

char16_t PdxInstanceImpl::getCharField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readInt16();
}

std::string PdxInstanceImpl::getStringField(const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readString();
}

std::vector<bool> PdxInstanceImpl::getBooleanArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readBooleanArray();
}

std::vector<int8_t> PdxInstanceImpl::getByteArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readByteArray();
}

std::vector<int16_t> PdxInstanceImpl::getShortArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readShortArray();
}

std::vector<int32_t> PdxInstanceImpl::getIntArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readIntArray();
}

std::vector<int64_t> PdxInstanceImpl::getLongArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readLongArray();
}

std::vector<float> PdxInstanceImpl::getFloatArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readFloatArray();
}

std::vector<double> PdxInstanceImpl::getDoubleArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readDoubleArray();
}

std::vector<char16_t> PdxInstanceImpl::getCharArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readCharArray();
}

std::vector<std::string> PdxInstanceImpl::getStringArrayField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  return input.readStringArray();
}

std::shared_ptr<CacheableDate> PdxInstanceImpl::getCacheableDateField(
    const std::string& name) const {
  auto input = getDataInputForField(name);
  auto value = CacheableDate::create();
  value->fromData(input);
  return value;
}

std::shared_ptr<Cacheable> PdxInstanceImpl::getCacheableField(
    const std::string& name) const {
  auto dataInput = getDataInputForField(name);
  std::shared_ptr<Cacheable> value;
  dataInput.readObject(value);
  return value;
}
std::shared_ptr<CacheableObjectArray>
PdxInstanceImpl::getCacheableObjectArrayField(const std::string& name) const {
  auto dataInput = getDataInputForField(name);
  auto value = CacheableObjectArray::create();
  value->fromData(dataInput);
  return value;
}

void PdxInstanceImpl::getField(const std::string& name, int8_t*** value,
                               int32_t& arrayLength,
                               int32_t*& elementLength) const {
  auto dataInput = getDataInputForField(name);
  dataInput.readArrayOfByteArrays(value, arrayLength, &elementLength);
}

std::string PdxInstanceImpl::toString() const {
  std::string result = "PDX[" + std::to_string(pdxType_->getTypeId()) + "," +
                       pdxType_->getPdxClassName() + "]{";
  bool firstElement = true;
  auto identityFields = getIdentityPdxFields();
  for (size_t i = 0; i < identityFields.size(); i++) {
    if (firstElement) {
      firstElement = false;
    } else {
      result += ",";
    }
    result += identityFields.at(i)->getFieldName();
    result += "=";

    switch (identityFields.at(i)->getTypeId()) {
      case PdxFieldTypes::BOOLEAN: {
        auto&& value = getBooleanField(identityFields.at(i)->getFieldName());
        result += value ? "true" : "false";
        break;
      }
      case PdxFieldTypes::BYTE: {
        auto&& value = getByteField(identityFields.at(i)->getFieldName());
        result += std::to_string(value);
        break;
      }
      case PdxFieldTypes::SHORT: {
        int16_t value = getShortField(identityFields.at(i)->getFieldName());
        result += std::to_string(value);
        break;
      }
      case PdxFieldTypes::INT: {
        int32_t value = getIntField(identityFields.at(i)->getFieldName());
        result += std::to_string(value);
        break;
      }
      case PdxFieldTypes::LONG: {
        int64_t value = getLongField(identityFields.at(i)->getFieldName());
        result += std::to_string(value);
        break;
      }
      case PdxFieldTypes::FLOAT: {
        float value = getFloatField(identityFields.at(i)->getFieldName());
        result += std::to_string(value);
        break;
      }
      case PdxFieldTypes::DOUBLE: {
        double value = getDoubleField(identityFields.at(i)->getFieldName());
        result += std::to_string(value);
        break;
      }
      case PdxFieldTypes::CHAR: {
        auto value = getCharField(identityFields.at(i)->getFieldName());
        result += to_utf8(std::u16string{value});
        break;
      }
      case PdxFieldTypes::STRING: {
        auto value = getStringField(identityFields.at(i)->getFieldName());
        result += value;
        break;
      }
      case PdxFieldTypes::CHAR_ARRAY: {
        auto value = getCharArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          result += to_utf8(std::u16string(value.data(), length));
        }
        break;
      }
      case PdxFieldTypes::STRING_ARRAY: {
        auto value = getStringArrayField(identityFields.at(i)->getFieldName());
        for (auto&& v : value) {
          result += v;
        }
        break;
      }
      case PdxFieldTypes::BYTE_ARRAY: {
        auto value = getByteArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          for (auto&& v : value) {
            result += std::to_string(v);
          }
        }
        break;
      }
      case PdxFieldTypes::SHORT_ARRAY: {
        auto value = getShortArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          for (auto&& v : value) {
            result += std::to_string(v);
          }
        }
        break;
      }
      case PdxFieldTypes::INT_ARRAY: {
        auto value = getIntArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          for (auto&& v : value) {
            result += std::to_string(v);
          }
        }
        break;
      }
      case PdxFieldTypes::LONG_ARRAY: {
        auto value = getLongArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          for (auto&& v : value) {
            result += std::to_string(v);
          }
        }
        break;
      }
      case PdxFieldTypes::FLOAT_ARRAY: {
        auto value = getFloatArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          for (auto&& v : value) {
            result += std::to_string(v);
          }
        }
        break;
      }
      case PdxFieldTypes::DOUBLE_ARRAY: {
        auto value = getDoubleArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          for (auto&& v : value) {
            result += std::to_string(v);
          }
        }
        break;
      }
      case PdxFieldTypes::DATE: {
        auto value =
            getCacheableDateField(identityFields.at(i)->getFieldName());
        if (value != nullptr) {
          result += value->toString().c_str();
        }
        break;
      }
      case PdxFieldTypes::BOOLEAN_ARRAY: {
        auto value = getBooleanArrayField(identityFields.at(i)->getFieldName());
        auto length = value.size();
        if (length > 0) {
          for (auto&& v : value) {
            result += v ? "true" : "false";
          }
        }
        break;
      }
      case PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS: {
        int8_t** value = nullptr;
        int32_t arrayLength;
        int32_t* elementLength;
        getField(identityFields.at(i)->getFieldName(), &value, arrayLength,
                 elementLength);
        if (arrayLength > 0) {
          for (int j = 0; j < arrayLength; j++) {
            for (int k = 0; k < elementLength[j]; k++) {
              result += std::to_string(value[j][k]);
            }
          }
        }
        break;
      }
      case PdxFieldTypes::OBJECT_ARRAY: {
        auto value =
            getCacheableObjectArrayField(identityFields.at(i)->getFieldName());
        if (value != nullptr) {
          result += value->toString().c_str();
        }
        break;
      }
      case PdxFieldTypes::OBJECT:
      case PdxFieldTypes::UNKNOWN: {
        auto value = getCacheableField(identityFields.at(i)->getFieldName());
        if (value != nullptr) {
          result += value->toString().c_str();
        }
      }
    }
  }
  result += "}";

  return result;
}

std::shared_ptr<PdxSerializable> PdxInstanceImpl::getObject() {
  const auto& stream = getPdxStream();
  auto len = stream.size();

  auto input = cacheImpl_.createDataInput(stream.data(), len);
  getPdxType(DataInputInternal::getPool(input));

  int64_t sampleStartNanos =
      enableTimeStatistics_ ? Utils::startStatOpTime() : 0;

  //[ToDo] do we have to call incPdxDeSerialization here?
  auto ret =
      PdxHelper::deserializePdx(input, typeId_, static_cast<int32_t>(len));

  if (enableTimeStatistics_) {
    Utils::updateStatOpTime(cacheStats_.getStat(),
                            cacheStats_.getPdxInstanceDeserializationTimeId(),
                            sampleStartNanos);
  }

  cacheStats_.incPdxInstanceDeserializations();
  return ret;
}

void PdxInstanceImpl::equatePdxFields(
    std::vector<std::shared_ptr<PdxFieldType>>& my,
    std::vector<std::shared_ptr<PdxFieldType>>& other) const {
  int otherIdx = -1;
  for (int32_t i = 0; i < static_cast<int32_t>(my.size()); i++) {
    auto myF = my.at(i);
    if (!myF->equals(DEFAULT_PDX_FIELD_TYPE)) {
      for (int32_t j = 0; j < static_cast<int32_t>(other.size()); j++) {
        if (myF->equals(other[j])) {
          otherIdx = j;
          break;
        } else {
          otherIdx = -1;
        }
      }

      if (otherIdx == -1)  // field not there
      {
        if (i < static_cast<int32_t>(other.size())) {
          auto tmp = other.at(i);
          other.at(i) = DEFAULT_PDX_FIELD_TYPE;
          other.push_back(tmp);
        } else {
          other.push_back(DEFAULT_PDX_FIELD_TYPE);
        }
      } else if (otherIdx != i) {
        auto tmp = other.at(i);
        other.at(i) = other.at(otherIdx);
        other.at(otherIdx) = tmp;
      }
    }
  }
}

bool PdxInstanceImpl::operator==(const CacheableKey& o) const {
  PdxInstanceImpl* other =
      dynamic_cast<PdxInstanceImpl*>(const_cast<CacheableKey*>(&o));

  if (other == nullptr) {
    return false;
  }

  auto otherType = other->pdxType_;
  if (pdxType_->getPdxClassName() != otherType->getPdxClassName()) {
    return false;
  }

  auto identityFields = getIdentityPdxFields();
  auto otherIdentityFields = other->getIdentityPdxFields();

  equatePdxFields(identityFields, otherIdentityFields);
  equatePdxFields(otherIdentityFields, identityFields);

  auto stream = getPdxStream();
  auto otherStream = other->getPdxStream();

  auto input = cacheImpl_.createDataInput(stream.data(), stream.size());
  auto otherInput =
      cacheImpl_.createDataInput(otherStream.data(), otherStream.size());

  PdxFieldTypes fieldTypeId;
  for (size_t i = 0; i < identityFields.size(); i++) {
    auto myPFT = identityFields.at(i);
    auto otherPFT = otherIdentityFields.at(i);

    LOGDEBUG("pdxfield %s ",
             ((myPFT != DEFAULT_PDX_FIELD_TYPE) ? myPFT->getFieldName()
                                                : otherPFT->getFieldName())
                 .c_str());
    if (myPFT->equals(DEFAULT_PDX_FIELD_TYPE)) {
      fieldTypeId = otherPFT->getTypeId();
    } else if (otherPFT->equals(DEFAULT_PDX_FIELD_TYPE)) {
      fieldTypeId = myPFT->getTypeId();
    } else {
      fieldTypeId = myPFT->getTypeId();
    }

    switch (fieldTypeId) {
      case PdxFieldTypes::CHAR:
      case PdxFieldTypes::BOOLEAN:
      case PdxFieldTypes::BYTE:
      case PdxFieldTypes::SHORT:
      case PdxFieldTypes::INT:
      case PdxFieldTypes::LONG:
      case PdxFieldTypes::DATE:
      case PdxFieldTypes::FLOAT:
      case PdxFieldTypes::DOUBLE:
      case PdxFieldTypes::STRING:
      case PdxFieldTypes::BOOLEAN_ARRAY:
      case PdxFieldTypes::CHAR_ARRAY:
      case PdxFieldTypes::BYTE_ARRAY:
      case PdxFieldTypes::SHORT_ARRAY:
      case PdxFieldTypes::INT_ARRAY:
      case PdxFieldTypes::LONG_ARRAY:
      case PdxFieldTypes::FLOAT_ARRAY:
      case PdxFieldTypes::DOUBLE_ARRAY:
      case PdxFieldTypes::STRING_ARRAY:
      case PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS: {
        if (!compareRawBytes(input, otherInput, *other, myPFT, otherPFT)) {
          return false;
        }
        break;
      }
      case PdxFieldTypes::OBJECT: {
        std::shared_ptr<Cacheable> object = nullptr;
        std::shared_ptr<Cacheable> otherObject = nullptr;
        if (!myPFT->equals(DEFAULT_PDX_FIELD_TYPE)) {
          setOffsetForObject(input, myPFT->getSequenceId());
          input.readObject(object);
        }

        if (!otherPFT->equals(DEFAULT_PDX_FIELD_TYPE)) {
          other->setOffsetForObject(otherInput, otherPFT->getSequenceId());
          otherInput.readObject(otherObject);
        }

        if (object != nullptr) {
          if (!deepArrayEquals(object, otherObject)) {
            return false;
          }
        } else if (otherObject != nullptr) {
          return false;
        }
        break;
      }
      case PdxFieldTypes::OBJECT_ARRAY: {
        auto otherObjectArray = CacheableObjectArray::create();
        auto objectArray = CacheableObjectArray::create();

        if (!myPFT->equals(DEFAULT_PDX_FIELD_TYPE)) {
          setOffsetForObject(input, myPFT->getSequenceId());
          objectArray->fromData(input);
        }

        if (!otherPFT->equals(DEFAULT_PDX_FIELD_TYPE)) {
          other->setOffsetForObject(otherInput, otherPFT->getSequenceId());
          otherObjectArray->fromData(otherInput);
        }
        if (!deepArrayEquals(objectArray, otherObjectArray)) {
          return false;
        }
        break;
      }
      case PdxFieldTypes::UNKNOWN: {
        throw IllegalStateException(
            std::string("PdxInstance not found typeid ") +
            std::to_string(static_cast<int>(myPFT->getTypeId())));
      }
    }
  }

  return true;
}

bool PdxInstanceImpl::compareRawBytes(
    DataInput& input, DataInput& otherInput, PdxInstanceImpl& other,
    std::shared_ptr<PdxFieldType> field,
    std::shared_ptr<PdxFieldType> otherField) const {
  auto otherType = other.pdxType_;
  if (!field->equals(DEFAULT_PDX_FIELD_TYPE) &&
      !otherField->equals(DEFAULT_PDX_FIELD_TYPE)) {
    auto pos = getOffset(input, field->getSequenceId());
    auto nextpos = getNextFieldPosition(input, field->getSequenceId() + 1);
    input.reset();
    input.advanceCursor(pos);

    auto otherPos = other.getOffset(otherInput, otherField->getSequenceId());
    int otherNextpos =
        other.getNextFieldPosition(otherInput, otherField->getSequenceId() + 1);
    otherInput.reset();
    otherInput.advanceCursor(otherPos);

    if ((nextpos - pos) != (otherNextpos - otherPos)) {
      return false;
    }

    for (int i = pos; i < nextpos; i++) {
      if (input.read() != otherInput.read()) {
        return false;
      }
    }

    return true;
  } else {
    if (field->equals(DEFAULT_PDX_FIELD_TYPE)) {
      int otherPos = other.getOffset(otherInput, otherField->getSequenceId());
      int otherNextpos = other.getNextFieldPosition(
          otherInput, otherField->getSequenceId() + 1);
      return hasDefaultBytes(otherField, otherInput, otherPos, otherNextpos);
    } else {
      int pos = getOffset(input, field->getSequenceId());
      int nextpos = getNextFieldPosition(input, field->getSequenceId() + 1);
      return hasDefaultBytes(field, input, pos, nextpos);
    }
  }
}

std::shared_ptr<CacheableStringArray> PdxInstanceImpl::getFieldNames() {
  std::vector<std::shared_ptr<PdxFieldType>>* vectorOfFieldTypes =
      pdxType_->getPdxFieldTypes();
  auto size = vectorOfFieldTypes->size();
  if (size == 0) {
    return nullptr;
  }

  std::vector<std::shared_ptr<CacheableString>> tmpFieldNames;
  tmpFieldNames.reserve(size);
  for (auto&& fieldType : *vectorOfFieldTypes) {
    tmpFieldNames.emplace_back(
        CacheableString::create(fieldType->getFieldName()));
  }
  return CacheableStringArray::create(std::move(tmpFieldNames));
}

PdxFieldTypes PdxInstanceImpl::getFieldType(const std::string& name) const {
  auto field = pdxType_->getPdxField(name);

  if (!field) {
    throw IllegalStateException("PdxInstance doesn't have field " + name);
  }

  return field->getTypeId();
}

void PdxInstanceImpl::writeUnmodifieldField(DataInput& dataInput, int startPos,
                                            int endPos,
                                            PdxLocalWriter& localWriter) {
  dataInput.reset(startPos);
  for (; startPos < endPos; startPos++) {
    localWriter.writeByte(dataInput.read());
  }
}

void PdxInstanceImpl::toData(PdxWriter& writer) const {
  const_cast<PdxInstanceImpl*>(this)->toDataMutable(writer);
}

void PdxInstanceImpl::toDataMutable(PdxWriter& writer) {
  std::vector<std::shared_ptr<PdxFieldType>>* pdxFieldList =
      pdxType_->getPdxFieldTypes();
  int position = 0;  // ignore typeid and length
  int nextFieldPosition = 0;
  if (buffer_.size() != 0) {
    auto dataInput = cacheImpl_.createDataInput(buffer_.data(), buffer_.size());
    for (size_t i = 0; i < pdxFieldList->size(); i++) {
      auto currPf = pdxFieldList->at(i);
      LOGDEBUG("toData fieldName = %s , isVarLengthType = %d ",
               currPf->getFieldName().c_str(), currPf->IsVariableLengthType());
      std::shared_ptr<Cacheable> value = nullptr;

      auto&& iter = m_updatedFields.find(currPf->getFieldName());
      if (iter != m_updatedFields.end()) {
        value = iter->second;
      } else {
        value = nullptr;
      }
      if (value != nullptr) {
        writeField(writer, currPf->getFieldName(), currPf->getTypeId(), value);
        position = getNextFieldPosition(dataInput, static_cast<int>(i) + 1);
      } else {
        if (currPf->IsVariableLengthType()) {
          // need to add offset
          (static_cast<PdxLocalWriter&>(writer)).addOffset();
        }
        // write raw byte array...
        nextFieldPosition =
            getNextFieldPosition(dataInput, static_cast<int>(i) + 1);
        writeUnmodifieldField(dataInput, position, nextFieldPosition,
                              static_cast<PdxLocalWriter&>(writer));
        position = nextFieldPosition;  // mark next field;
      }
    }
  } else {
    for (size_t i = 0; i < pdxFieldList->size(); i++) {
      auto currPf = pdxFieldList->at(i);
      LOGDEBUG("toData1 fieldName = %s , isVarLengthType = %d ",
               currPf->getFieldName().c_str(), currPf->IsVariableLengthType());
      auto value = m_updatedFields[currPf->getFieldName()];
      writeField(writer, currPf->getFieldName(), currPf->getTypeId(), value);
    }
  }
  m_updatedFields.clear();
}

void PdxInstanceImpl::fromData(PdxReader&) {
  throw IllegalStateException(
      "PdxInstance::FromData( .. ) shouldn't have called");
}

const std::string& PdxInstanceImpl::getClassName() const {
  return pdxType_->getPdxClassName();
}

std::vector<std::shared_ptr<PdxFieldType>>
PdxInstanceImpl::getIdentityPdxFields() const {
  std::vector<std::shared_ptr<PdxFieldType>> result;
  const auto& fields = *pdxType_->getPdxFieldTypes();

  for (const auto& field : fields) {
    if (field->getIdentityField()) {
      result.push_back(field);
    }
  }

  if (result.empty()) {
    result = fields;
  }

  std::sort(result.begin(), result.end(),
            [](std::shared_ptr<PdxFieldType> first,
               std::shared_ptr<PdxFieldType> second) {
              return first->getFieldName() < second->getFieldName();
            });

  return result;
}

int PdxInstanceImpl::getOffset(DataInput& input, int sequenceId) const {
  input.resetPdx(0);

  int offsetSize = 0;
  int serializedLength = 0;
  int pdxSerializedLength = static_cast<int32_t>(input.getPdxBytes());

  LOGDEBUG("getOffset pdxSerializedLength = %d ", pdxSerializedLength);

  if (pdxSerializedLength <= 0xff) {
    offsetSize = 1;
  } else if (pdxSerializedLength <= 0xffff) {
    offsetSize = 2;
  } else {
    offsetSize = 4;
  }

  if (pdxType_->getNumberOfVarLenFields() > 0) {
    serializedLength = pdxSerializedLength -
                       ((pdxType_->getNumberOfVarLenFields() - 1) * offsetSize);
  } else {
    serializedLength = pdxSerializedLength;
  }

  //[ToDo see if currentBufferPosition can correctly replace GetCursor]
  uint8_t* offsetsBuffer =
      const_cast<uint8_t*>(input.currentBufferPosition()) + serializedLength;
  return pdxType_->getFieldPosition(sequenceId, offsetsBuffer, offsetSize,
                                    serializedLength);
}

int PdxInstanceImpl::getRawHashCode(DataInput& input,
                                    std::shared_ptr<PdxFieldType> field) const {
  auto pos = getOffset(input, field->getSequenceId());
  auto nextpos = getNextFieldPosition(input, field->getSequenceId() + 1);

  LOGDEBUG("pos = %d nextpos = %d ", pos, nextpos);

  if (hasDefaultBytes(field, input, pos, nextpos)) {
    return 0;  // matched default bytes
  }

  input.reset();
  input.advanceCursor(nextpos - 1);

  int h = 1;
  for (int i = nextpos - 1; i >= pos; i--) {
    h = 31 * h + static_cast<int>(input.read());
    input.reset();
    input.advanceCursor(i - 1);
  }
  LOGDEBUG("getRawHashCode nbytes = %d, final hashcode = %d ", (nextpos - pos),
           h);
  return h;
}

int PdxInstanceImpl::getNextFieldPosition(DataInput& input, int fieldId) const {
  LOGDEBUG("fieldId = %d pt->getTotalFields() = %d ", fieldId,
           pdxType_->getTotalFields());

  return fieldId == pdxType_->getTotalFields() ? getSerializedLength(input)
                                               : getOffset(input, fieldId);
}

int PdxInstanceImpl::getSerializedLength(DataInput& input) const {
  input.resetPdx(0);

  int offsetSize = 0;
  int serializedLength = 0;
  int pdxSerializedLength = static_cast<int32_t>(input.getPdxBytes());

  LOGDEBUG("pdxSerializedLength = %d ", pdxSerializedLength);

  if (pdxSerializedLength <= 0xff) {
    offsetSize = 1;
  } else if (pdxSerializedLength <= 0xffff) {
    offsetSize = 2;
  } else {
    offsetSize = 4;
  }

  if (pdxType_->getNumberOfVarLenFields() > 0) {
    serializedLength = pdxSerializedLength -
                       ((pdxType_->getNumberOfVarLenFields() - 1) * offsetSize);
  } else {
    serializedLength = pdxSerializedLength;
  }

  return serializedLength;
}

bool PdxInstanceImpl::compareDefaultBytes(DataInput& dataInput, int start,
                                          int end, int8_t* defaultBytes,
                                          int32_t length) const {
  if ((end - start) != length) return false;

  dataInput.reset();
  dataInput.advanceCursor(start);
  int j = 0;
  for (int i = start; i < end; i++) {
    if (defaultBytes[j++] != dataInput.read()) {
      return false;
    }
  }
  return true;
}

bool PdxInstanceImpl::hasDefaultBytes(std::shared_ptr<PdxFieldType> pField,
                                      DataInput& dataInput, int start,
                                      int end) const {
  switch (pField->getTypeId()) {
    case PdxFieldTypes::INT: {
      return compareDefaultBytes(dataInput, start, end, INT_DEFAULT_BYTES, 4);
    }
    case PdxFieldTypes::STRING: {
      return compareDefaultBytes(dataInput, start, end, STRING_DEFAULT_BYTES,
                                 1);
    }
    case PdxFieldTypes::BOOLEAN: {
      return compareDefaultBytes(dataInput, start, end, BOOLEAN_DEFAULT_BYTES,
                                 1);
    }
    case PdxFieldTypes::FLOAT: {
      return compareDefaultBytes(dataInput, start, end, FLOAT_DEFAULT_BYTES, 4);
    }
    case PdxFieldTypes::DOUBLE: {
      return compareDefaultBytes(dataInput, start, end, DOUBLE_DEFAULT_BYTES,
                                 8);
    }
    case PdxFieldTypes::CHAR: {
      return compareDefaultBytes(dataInput, start, end, CHAR_DEFAULT_BYTES, 2);
    }
    case PdxFieldTypes::BYTE: {
      return compareDefaultBytes(dataInput, start, end, BYTE_DEFAULT_BYTES, 1);
    }
    case PdxFieldTypes::SHORT: {
      return compareDefaultBytes(dataInput, start, end, SHORT_DEFAULT_BYTES, 2);
    }
    case PdxFieldTypes::LONG: {
      return compareDefaultBytes(dataInput, start, end, LONG_DEFAULT_BYTES, 8);
    }
    case PdxFieldTypes::BYTE_ARRAY:
    case PdxFieldTypes::DOUBLE_ARRAY:
    case PdxFieldTypes::FLOAT_ARRAY:
    case PdxFieldTypes::SHORT_ARRAY:
    case PdxFieldTypes::INT_ARRAY:
    case PdxFieldTypes::LONG_ARRAY:
    case PdxFieldTypes::BOOLEAN_ARRAY:
    case PdxFieldTypes::CHAR_ARRAY:
    case PdxFieldTypes::STRING_ARRAY:
    case PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS:
    case PdxFieldTypes::OBJECT_ARRAY: {
      return compareDefaultBytes(dataInput, start, end,
                                 NULL_ARRAY_DEFAULT_BYTES, 1);
    }
    case PdxFieldTypes::DATE: {
      return compareDefaultBytes(dataInput, start, end, DATE_DEFAULT_BYTES, 8);
    }
    case PdxFieldTypes::OBJECT: {
      return compareDefaultBytes(dataInput, start, end, OBJECT_DEFAULT_BYTES,
                                 1);
    }
    case PdxFieldTypes::UNKNOWN: {
      throw IllegalStateException("hasDefaultBytes unable to find typeID ");
    }
  }
  throw IllegalStateException("hasDefaultBytes unable to find typeID ");
}

void PdxInstanceImpl::setField(const std::string& name, bool value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::BOOLEAN) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableBoolean::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, signed char value) {
  auto field = pdxType_->getPdxField(name);

  if (field != nullptr && field->getTypeId() != PdxFieldTypes::BYTE) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableByte::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, unsigned char value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::BYTE) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }
  auto cacheableObject = CacheableByte::create(value);
  m_updatedFields[name] = cacheableObject;
}

void PdxInstanceImpl::setField(const std::string& name, int16_t value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::SHORT) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableInt16::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, int32_t value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::INT) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableInt32::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, int64_t value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::LONG) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableInt64::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, float value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::FLOAT) {
    throw IllegalStateException(
        "PdxInstance doesn't have field " + name +
        " or type of field not matched " +
        (field != nullptr ? field->toString().c_str() : ""));
  }

  m_updatedFields[name] = CacheableFloat::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, double value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::DOUBLE) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableDouble::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, char16_t value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::CHAR) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableCharacter::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               std::shared_ptr<CacheableDate> value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::DATE) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = value;
}

void PdxInstanceImpl::setField(const std::string& name,
                               std::shared_ptr<Cacheable> value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::OBJECT) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }
  m_updatedFields[name] = value;
}

void PdxInstanceImpl::setField(const std::string& name,
                               std::shared_ptr<CacheableObjectArray> value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::OBJECT_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }
  m_updatedFields[name] = value;
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<bool>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::BOOLEAN_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = BooleanArray::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<int8_t>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::BYTE_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableBytes::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<int16_t>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::SHORT_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableInt16Array::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<int32_t>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::INT_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableInt32Array::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<int64_t>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::LONG_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableInt64Array::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<float>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::FLOAT_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableFloatArray::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<double>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::DOUBLE_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableDoubleArray::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::vector<char16_t>& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::CHAR_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CharArray::create(value);
}

void PdxInstanceImpl::setField(const std::string& name,
                               const std::string& value) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::STRING) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  m_updatedFields[name] = CacheableString::create(value);
}

void PdxInstanceImpl::setField(const std::string& name, int8_t** value,
                               int32_t arrayLength, int32_t* elementLength) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr &&
      field->getTypeId() != PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }
  auto cacheableObject = CacheableVector::create();
  for (int i = 0; i < arrayLength; i++) {
    auto ptr = CacheableBytes::create(
        std::vector<int8_t>(value[i], value[i] + elementLength[i]));
    cacheableObject->push_back(ptr);
  }

  m_updatedFields[name] = cacheableObject;
}

void PdxInstanceImpl::setField(const std::string& name, std::string* value,
                               int32_t length) {
  auto field = pdxType_->getPdxField(name);
  if (field != nullptr && field->getTypeId() != PdxFieldTypes::STRING_ARRAY) {
    throw IllegalStateException("PdxInstance doesn't have field " + name +
                                " or type of field not matched " +
                                (field != nullptr ? field->toString() : ""));
  }

  if (length > 0) {
    std::vector<std::shared_ptr<CacheableString>> tmpValues;
    tmpValues.reserve(length);
    for (int32_t i = 0; i < length; ++i) {
      tmpValues.emplace_back(CacheableString::create(value[i]));
    }
    m_updatedFields[name] = CacheableStringArray::create(std::move(tmpValues));
  }
}

void PdxInstanceImpl::setOffsetForObject(DataInput& input,
                                         int sequenceId) const {
  int pos = getOffset(input, sequenceId);

  input.reset();
  input.advanceCursor(pos);
}

size_t PdxInstanceImpl::objectSize() const {
  auto size = sizeof(PdxInstanceImpl);
  size += buffer_.size();
  size += pdxType_->objectSize();
  for (FieldVsValues::const_iterator iter = m_updatedFields.begin();
       iter != m_updatedFields.end(); ++iter) {
    size += iter->first.length();
    size += iter->second->objectSize();
  }
  return size;
}

PdxTypeRegistry& PdxInstanceImpl::getPdxTypeRegistry() const {
  return pdxTypeRegistry_;
}

DataInput PdxInstanceImpl::getDataInputForField(const std::string& name) const {
  auto field = pdxType_->getPdxField(name);

  if (!field) {
    throw IllegalStateException("PdxInstance doesn't have field " + name);
  }

  auto dataInput = cacheImpl_.createDataInput(buffer_.data(), buffer_.size());
  auto pos = getOffset(dataInput, field->getSequenceId());

  dataInput.reset();
  dataInput.advanceCursor(pos);

  return dataInput;
}

}  // namespace client
}  // namespace geode
}  // namespace apache
