/*
 * 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.
 */

#pragma once

#ifndef GEODE_INTEGRATION_TEST_THINCLIENTPDXSERIALIZERS_H_
#define GEODE_INTEGRATION_TEST_THINCLIENTPDXSERIALIZERS_H_

namespace {  // NOLINT(google-build-namespaces)

using apache::geode::client::CacheableArrayList;
using apache::geode::client::CacheableHashMap;
using apache::geode::client::CacheableHashSet;
using apache::geode::client::CacheableHashTable;
using apache::geode::client::CacheableLinkedHashSet;
using apache::geode::client::CacheableVector;
using apache::geode::client::PdxReader;
using apache::geode::client::PdxSerializer;
using apache::geode::client::PdxWriter;
using apache::geode::client::UserObjectSizer;

using PdxTests::TestPdxSerializerForV2;
using PdxTests::V1CLASSNAME2;
using PdxTests::V2CLASSNAME4;

static const char* CLASSNAME1 = "PdxTests.PdxType";
static const char* CLASSNAME2 = "PdxTests.Address";

class TestPdxSerializer : public PdxSerializer {
 public:
  static void deallocate(void* testObject, const std::string& className) {
    ASSERT(className == CLASSNAME1 || className == CLASSNAME2,
           "Unexpected classname in deallocate()");
    LOG("TestPdxSerializer::deallocate called");
    if (className == CLASSNAME1) {
      PdxTests::NonPdxType* nonPdxType =
          reinterpret_cast<PdxTests::NonPdxType*>(testObject);
      delete nonPdxType;
    } else {
      PdxTests::NonPdxAddress* nonPdxAddress =
          reinterpret_cast<PdxTests::NonPdxAddress*>(testObject);
      delete nonPdxAddress;
    }
  }

  static size_t objectSize(const std::shared_ptr<const void>&,
                           const std::string& className) {
    ASSERT(className == CLASSNAME1 || className == CLASSNAME2,
           "Unexpected classname in objectSize()");
    LOG("TestPdxSerializer::objectSize called");
    return 12345;  // dummy value
  }

  UserObjectSizer getObjectSizer(const std::string& className) override {
    ASSERT(className == CLASSNAME1 || className == CLASSNAME2,
           "Unexpected classname in getObjectSizer");
    return objectSize;
  }

  std::shared_ptr<void> fromDataForAddress(PdxReader& pr) {
    try {
      auto nonPdxAddress = std::make_shared<PdxTests::NonPdxAddress>();
      nonPdxAddress->_aptNumber = pr.readInt("_aptNumber");
      nonPdxAddress->_street = pr.readString("_street");
      nonPdxAddress->_city = pr.readString("_city");
      return std::move(nonPdxAddress);
    } catch (...) {
      return nullptr;
    }
  }

  std::shared_ptr<void> fromData(const std::string& className,
                                 PdxReader& pdxReader) override {
    ASSERT(className == CLASSNAME1 || className == CLASSNAME2,
           "Unexpected classname in fromData");

    if (className == CLASSNAME2) {
      return fromDataForAddress(pdxReader);
    }

    auto nonPdxType = std::make_shared<PdxTests::NonPdxType>();

    try {
      int32_t* Lengtharr;
      int32_t arrLen = 0;
      nonPdxType->deleteByteByteArray();
      nonPdxType->m_byteByteArray = pdxReader.readArrayOfByteArrays(
          "m_byteByteArray", arrLen, &Lengtharr);
      _GEODE_SAFE_DELETE_ARRAY(Lengtharr);

      // TODO::need to write compareByteByteArray() and check for
      // m_byteByteArray elements

      nonPdxType->m_char = pdxReader.readChar("m_char");
      // GenericValCompare

      nonPdxType->m_bool = pdxReader.readBoolean("m_bool");
      // GenericValCompare
      nonPdxType->m_boolArray = pdxReader.readBooleanArray("m_boolArray");

      nonPdxType->m_byte = pdxReader.readByte("m_byte");
      nonPdxType->m_byteArray = pdxReader.readByteArray("m_byteArray");
      nonPdxType->m_charArray = pdxReader.readCharArray("m_charArray");

      nonPdxType->m_arraylist = std::dynamic_pointer_cast<CacheableArrayList>(
          pdxReader.readObject("m_arraylist"));

      nonPdxType->m_map = std::dynamic_pointer_cast<CacheableHashMap>(
          pdxReader.readObject("m_map"));
      // TODO:Check for the size

      nonPdxType->m_hashtable = std::dynamic_pointer_cast<CacheableHashTable>(
          pdxReader.readObject("m_hashtable"));
      // TODO:Check for the size

      nonPdxType->m_vector = std::dynamic_pointer_cast<CacheableVector>(
          pdxReader.readObject("m_vector"));
      // TODO::Check for size

      nonPdxType->m_chs = std::dynamic_pointer_cast<CacheableHashSet>(
          pdxReader.readObject("m_chs"));
      // TODO::Size check

      nonPdxType->m_clhs = std::dynamic_pointer_cast<CacheableLinkedHashSet>(
          pdxReader.readObject("m_clhs"));
      // TODO:Size check

      nonPdxType->m_string =
          pdxReader.readString("m_string");  // GenericValCompare
      nonPdxType->m_date = pdxReader.readDate("m_dateTime");  // compareData

      nonPdxType->m_double = pdxReader.readDouble("m_double");

      nonPdxType->m_doubleArray = pdxReader.readDoubleArray("m_doubleArray");
      nonPdxType->m_float = pdxReader.readFloat("m_float");
      nonPdxType->m_floatArray = pdxReader.readFloatArray("m_floatArray");
      nonPdxType->m_int16 = pdxReader.readShort("m_int16");
      nonPdxType->m_int32 = pdxReader.readInt("m_int32");
      nonPdxType->m_long = pdxReader.readLong("m_long");
      nonPdxType->m_int32Array = pdxReader.readIntArray("m_int32Array");
      nonPdxType->m_longArray = pdxReader.readLongArray("m_longArray");
      nonPdxType->m_int16Array = pdxReader.readShortArray("m_int16Array");
      nonPdxType->m_sbyte = pdxReader.readByte("m_sbyte");
      nonPdxType->m_sbyteArray = pdxReader.readByteArray("m_sbyteArray");
      nonPdxType->m_stringArray = pdxReader.readStringArray("m_stringArray");
      nonPdxType->m_uint16 = pdxReader.readShort("m_uint16");
      nonPdxType->m_uint32 = pdxReader.readInt("m_uint32");
      nonPdxType->m_ulong = pdxReader.readLong("m_ulong");
      nonPdxType->m_uint32Array = pdxReader.readIntArray("m_uint32Array");
      nonPdxType->m_ulongArray = pdxReader.readLongArray("m_ulongArray");
      nonPdxType->m_uint16Array = pdxReader.readShortArray("m_uint16Array");

      nonPdxType->m_byte252 = pdxReader.readByteArray("m_byte252");
      nonPdxType->m_byte253 = pdxReader.readByteArray("m_byte253");
      nonPdxType->m_byte65535 = pdxReader.readByteArray("m_byte65535");
      nonPdxType->m_byte65536 = pdxReader.readByteArray("m_byte65536");

      nonPdxType->m_pdxEnum = pdxReader.readObject("m_pdxEnum");

      nonPdxType->m_address = pdxReader.readObject("m_address");

      nonPdxType->m_objectArray = pdxReader.readObjectArray("m_objectArray");

      LOGINFO("TestPdxSerializer: NonPdxType fromData() Done.");
    } catch (...) {
      return nullptr;
    }
    return std::move(nonPdxType);
  }

  bool toDataForAddress(const std::shared_ptr<const void>& testObject,
                        PdxWriter& pdxWriter) {
    try {
      auto nonPdxAddress =
          std::static_pointer_cast<const PdxTests::NonPdxAddress>(testObject);
      pdxWriter.writeInt("_aptNumber", nonPdxAddress->_aptNumber);
      pdxWriter.writeString("_street", nonPdxAddress->_street);
      pdxWriter.writeString("_city", nonPdxAddress->_city);
      return true;
    } catch (...) {
      return false;
    }
  }

  bool toData(const std::shared_ptr<const void>& testObject,
              const std::string& className, PdxWriter& pdxWriter) override {
    ASSERT(className == CLASSNAME1 || className == CLASSNAME2,
           "Unexpected classname in toData");

    if (className == CLASSNAME2) {
      return toDataForAddress(testObject, pdxWriter);
    }

    auto nonPdxType =
        std::static_pointer_cast<const PdxTests::NonPdxType>(testObject);

    try {
      int lengthArr[2];

      lengthArr[0] = 1;
      lengthArr[1] = 2;
      pdxWriter.writeArrayOfByteArrays(
          "m_byteByteArray", nonPdxType->m_byteByteArray, 2, lengthArr);
      pdxWriter.writeChar("m_char", nonPdxType->m_char);
      pdxWriter.markIdentityField("m_char");
      pdxWriter.writeBoolean("m_bool", nonPdxType->m_bool);  // 1
      pdxWriter.markIdentityField("m_bool");
      pdxWriter.writeBooleanArray("m_boolArray", nonPdxType->m_boolArray);
      pdxWriter.markIdentityField("m_boolArray");
      pdxWriter.writeByte("m_byte", nonPdxType->m_byte);
      pdxWriter.markIdentityField("m_byte");
      pdxWriter.writeByteArray("m_byteArray", nonPdxType->m_byteArray);
      pdxWriter.markIdentityField("m_byteArray");
      pdxWriter.writeCharArray("m_charArray", nonPdxType->m_charArray);
      pdxWriter.markIdentityField("m_charArray");
      pdxWriter.writeObject("m_arraylist", nonPdxType->m_arraylist);
      pdxWriter.markIdentityField("m_arraylist");
      pdxWriter.writeObject("m_map", nonPdxType->m_map);
      pdxWriter.markIdentityField("m_map");
      pdxWriter.writeObject("m_hashtable", nonPdxType->m_hashtable);
      pdxWriter.markIdentityField("m_hashtable");
      pdxWriter.writeObject("m_vector", nonPdxType->m_vector);
      pdxWriter.markIdentityField("m_vector");
      pdxWriter.writeObject("m_chs", nonPdxType->m_chs);
      pdxWriter.markIdentityField("m_chs");
      pdxWriter.writeObject("m_clhs", nonPdxType->m_clhs);
      pdxWriter.markIdentityField("m_clhs");
      pdxWriter.writeString("m_string", nonPdxType->m_string);
      pdxWriter.markIdentityField("m_string");
      pdxWriter.writeDate("m_dateTime", nonPdxType->m_date);
      pdxWriter.markIdentityField("m_dateTime");
      pdxWriter.writeDouble("m_double", nonPdxType->m_double);
      pdxWriter.markIdentityField("m_double");
      pdxWriter.writeDoubleArray("m_doubleArray", nonPdxType->m_doubleArray);
      pdxWriter.markIdentityField("m_doubleArray");
      pdxWriter.writeFloat("m_float", nonPdxType->m_float);
      pdxWriter.markIdentityField("m_float");
      pdxWriter.writeFloatArray("m_floatArray", nonPdxType->m_floatArray);
      pdxWriter.markIdentityField("m_floatArray");
      pdxWriter.writeShort("m_int16", nonPdxType->m_int16);
      pdxWriter.markIdentityField("m_int16");
      pdxWriter.writeInt("m_int32", nonPdxType->m_int32);
      pdxWriter.markIdentityField("m_int32");
      pdxWriter.writeLong("m_long", nonPdxType->m_long);
      pdxWriter.markIdentityField("m_long");
      pdxWriter.writeIntArray("m_int32Array", nonPdxType->m_int32Array);
      pdxWriter.markIdentityField("m_int32Array");
      pdxWriter.writeLongArray("m_longArray", nonPdxType->m_longArray);
      pdxWriter.markIdentityField("m_longArray");
      pdxWriter.writeShortArray("m_int16Array", nonPdxType->m_int16Array);
      pdxWriter.markIdentityField("m_int16Array");
      pdxWriter.writeByte("m_sbyte", nonPdxType->m_sbyte);
      pdxWriter.markIdentityField("m_sbyte");
      pdxWriter.writeByteArray("m_sbyteArray", nonPdxType->m_sbyteArray);
      pdxWriter.markIdentityField("m_sbyteArray");

      pdxWriter.writeStringArray("m_stringArray", nonPdxType->m_stringArray);
      pdxWriter.markIdentityField("m_stringArray");
      pdxWriter.writeShort("m_uint16", nonPdxType->m_uint16);
      pdxWriter.markIdentityField("m_uint16");
      pdxWriter.writeInt("m_uint32", nonPdxType->m_uint32);
      pdxWriter.markIdentityField("m_uint32");
      pdxWriter.writeLong("m_ulong", nonPdxType->m_ulong);
      pdxWriter.markIdentityField("m_ulong");
      pdxWriter.writeIntArray("m_uint32Array", nonPdxType->m_uint32Array);
      pdxWriter.markIdentityField("m_uint32Array");
      pdxWriter.writeLongArray("m_ulongArray", nonPdxType->m_ulongArray);
      pdxWriter.markIdentityField("m_ulongArray");
      pdxWriter.writeShortArray("m_uint16Array", nonPdxType->m_uint16Array);
      pdxWriter.markIdentityField("m_uint16Array");

      pdxWriter.writeByteArray("m_byte252", nonPdxType->m_byte252);
      pdxWriter.markIdentityField("m_byte252");
      pdxWriter.writeByteArray("m_byte253", nonPdxType->m_byte253);
      pdxWriter.markIdentityField("m_byte253");
      pdxWriter.writeByteArray("m_byte65535", nonPdxType->m_byte65535);
      pdxWriter.markIdentityField("m_byte65535");
      pdxWriter.writeByteArray("m_byte65536", nonPdxType->m_byte65536);
      pdxWriter.markIdentityField("m_byte65536");

      pdxWriter.writeObject("m_pdxEnum", nonPdxType->m_pdxEnum);
      pdxWriter.markIdentityField("m_pdxEnum");

      pdxWriter.writeObject("m_address", nonPdxType->m_objectArray);
      pdxWriter.writeObjectArray("m_objectArray", nonPdxType->m_objectArray);

      LOG("TestPdxSerializer: NonPdxType toData() Done......");
    } catch (...) {
      return false;
    }
    return true;
  }
};

}  // namespace

#endif  // GEODE_INTEGRATION_TEST_THINCLIENTPDXSERIALIZERS_H_
