/*
 * 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.
 */
/*
 * PdxReaderWithTypeCollector.cpp
 *
 *  Created on: Nov 3, 2011
 *      Author: npatel
 */

#include "PdxReaderWithTypeCollector.hpp"
#include "PdxTypes.hpp"
#include <ace/OS_NS_stdio.h>
#include <geode/PdxFieldTypes.hpp>
#include "CacheImpl.hpp"

namespace apache {
namespace geode {
namespace client {

PdxReaderWithTypeCollector::PdxReaderWithTypeCollector(
    DataInput& dataInput, std::shared_ptr<PdxType> pdxType, int32_t pdxlen,
    std::shared_ptr<PdxTypeRegistry> pdxTypeRegistry)
    : PdxLocalReader(dataInput, pdxType, pdxlen, pdxTypeRegistry) {
  m_newPdxType = std::make_shared<PdxType>(
      *m_pdxTypeRegistry, pdxType->getPdxClassName().c_str(), true);
}

PdxReaderWithTypeCollector::~PdxReaderWithTypeCollector() {}

void PdxReaderWithTypeCollector::checkType(const std::string& fieldName,
                                           PdxFieldTypes typeId,
                                           const std::string& fieldType) {
  auto pft = m_pdxType->getPdxField(fieldName);
  if (pft != nullptr) {
    if (typeId != pft->getTypeId()) {
      throw IllegalStateException("Expected " + fieldType +
                                  " fieldType field but found field of type " +
                                  pft->toString().c_str());
    }
  }
}

char16_t PdxReaderWithTypeCollector::readChar(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::CHAR, "char");
  m_newPdxType->addFixedLengthTypeField(fieldName, "char", PdxFieldTypes::CHAR,
                                        PdxTypes::CHAR_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readChar()position = %d", position);
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    auto retVal = PdxLocalReader::readChar(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::CHAR_SIZE);
    return retVal;
  } else {
    return 0;
  }
}

bool PdxReaderWithTypeCollector::readBoolean(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::BOOLEAN, "boolean");
  m_newPdxType->addFixedLengthTypeField(
      fieldName, "boolean", PdxFieldTypes::BOOLEAN, PdxTypes::BOOLEAN_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readBoolean():position = %d", position);
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    bool retVal = PdxLocalReader::readBoolean(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::BOOLEAN_SIZE);
    return retVal;
  } else {
    return 0;
  }
}

int8_t PdxReaderWithTypeCollector::readByte(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::BYTE, "byte");
  m_newPdxType->addFixedLengthTypeField(fieldName, "byte", PdxFieldTypes::BYTE,
                                        PdxTypes::BYTE_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readByte(): position = %d", position);
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    int8_t retVal;
    retVal = PdxLocalReader::readByte(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::BYTE_SIZE);
    return retVal;
  } else {
    return 0;
  }
}

int16_t PdxReaderWithTypeCollector::readShort(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::SHORT, "short");
  m_newPdxType->addFixedLengthTypeField(
      fieldName, "short", PdxFieldTypes::SHORT, PdxTypes::SHORT_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readShort(): position = %d", position);
  if (position != -1) {
    int16_t value;
    m_dataInput->advanceCursor(position);
    value = PdxLocalReader::readShort(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::SHORT_SIZE);
    return value;
  } else {
    return 0;
  }
}

int32_t PdxReaderWithTypeCollector::readInt(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::INT, "int");
  m_newPdxType->addFixedLengthTypeField(fieldName, "int", PdxFieldTypes::INT,
                                        PdxTypes::INTEGER_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readInt():position = %d", position);
  if (position != -1) {
    int32_t value;
    m_dataInput->advanceCursor(position);
    value = PdxLocalReader::readInt(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::INTEGER_SIZE);
    return value;
  } else {
    return 0;
  }
}

int64_t PdxReaderWithTypeCollector::readLong(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::LONG, "long");
  m_newPdxType->addFixedLengthTypeField(fieldName, "long", PdxFieldTypes::LONG,
                                        PdxTypes::LONG_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readLong(): position = %d", position);
  if (position != -1) {
    int64_t value;
    m_dataInput->advanceCursor(position);
    value = PdxLocalReader::readLong(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::LONG_SIZE);
    return value;
  } else {
    return 0;
  }
}

float PdxReaderWithTypeCollector::readFloat(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::FLOAT, "float");
  m_newPdxType->addFixedLengthTypeField(
      fieldName, "float", PdxFieldTypes::FLOAT, PdxTypes::FLOAT_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readFloat():position = %d", position);
  if (position != -1) {
    float value;
    m_dataInput->advanceCursor(position);
    value = PdxLocalReader::readFloat(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::FLOAT_SIZE);
    return value;
  } else {
    return 0.0f;
  }
}

double PdxReaderWithTypeCollector::readDouble(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::DOUBLE, "double");
  m_newPdxType->addFixedLengthTypeField(
      fieldName, "double", PdxFieldTypes::DOUBLE, PdxTypes::DOUBLE_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readDouble():position = %d", position);
  if (position != -1) {
    double value;
    m_dataInput->advanceCursor(position);
    value = PdxLocalReader::readDouble(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::DOUBLE_SIZE);
    return value;
  } else {
    return 0.0;
  }
}

std::string PdxReaderWithTypeCollector::readString(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::STRING, "String");
  m_newPdxType->addVariableLengthTypeField(fieldName, "String",
                                           PdxFieldTypes::STRING);
  int32_t position = m_pdxType->getFieldPosition(
      fieldName, m_offsetsBuffer, m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readString():position = %d", position);

  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    auto str = PdxLocalReader::readString(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
    return str;
  } else {
    return std::string();
  }
}

std::shared_ptr<Serializable> PdxReaderWithTypeCollector::readObject(
    const std::string& fieldName) {
  // field is collected after reading
  checkType(fieldName, PdxFieldTypes::OBJECT, "Serializable");
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readObject():position = %d", position);
  if (position != -1) {
    std::shared_ptr<Serializable> ptr;
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    ptr = PdxLocalReader::readObject(fieldName);
    m_newPdxType->addVariableLengthTypeField(fieldName, "Serializable",
                                             PdxFieldTypes::OBJECT);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
    return ptr;
  } else {
    return nullptr;
  }
}

std::vector<char16_t> PdxReaderWithTypeCollector::readCharArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::CHAR_ARRAY, "char[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "char[]",
                                           PdxFieldTypes::CHAR_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readCharArray():position = %d",
           position);
  std::vector<char16_t> array;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    array = PdxLocalReader::readCharArray(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return array;
}

std::vector<bool> PdxReaderWithTypeCollector::readBooleanArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::BOOLEAN_ARRAY, "boolean[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "boolean[]",
                                           PdxFieldTypes::BOOLEAN_ARRAY);
  LOGDEBUG("NIL:293: PdxReaderWithTypeCollector::readBooleanArray Test-1");
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG(
      "NIL:293: PdxReaderWithTypeCollector::readBooleanArray(): Position =%d ",
      position);

  std::vector<bool> array;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    array = PdxLocalReader::readBooleanArray(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return array;
}

std::vector<int8_t> PdxReaderWithTypeCollector::readByteArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::BYTE_ARRAY, "byte[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "byte[]",
                                           PdxFieldTypes::BYTE_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readByteArray(): position = %d",
           position);
  std::vector<int8_t> array;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    array = PdxLocalReader::readByteArray(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return array;
}

std::vector<int16_t> PdxReaderWithTypeCollector::readShortArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::SHORT_ARRAY, "short[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "short[]",
                                           PdxFieldTypes::SHORT_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readShortArray():position = %d",
           position);
  std::vector<int16_t> shortArrptr;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    shortArrptr = PdxLocalReader::readShortArray(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return shortArrptr;
}

std::vector<int32_t> PdxReaderWithTypeCollector::readIntArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::INT_ARRAY, "int[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "int[]",
                                           PdxFieldTypes::INT_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readIntArray():position = %d",
           position);
  std::vector<int32_t> intArrayptr;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    intArrayptr = PdxLocalReader::readIntArray(fieldName);
    auto strSize =m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return intArrayptr;
}

std::vector<int64_t> PdxReaderWithTypeCollector::readLongArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::LONG_ARRAY, "long[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "long[]",
                                           PdxFieldTypes::LONG_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readLongArray():position = %d",
           position);
  std::vector<int64_t> longArrptr;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    longArrptr = PdxLocalReader::readLongArray(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return longArrptr;
}

std::vector<float> PdxReaderWithTypeCollector::readFloatArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::FLOAT_ARRAY, "float[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "float[]",
                                           PdxFieldTypes::FLOAT_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readFloatArray(): position = %d",
           position);
  std::vector<float> floatArrptr;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    floatArrptr = PdxLocalReader::readFloatArray(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return floatArrptr;
}

std::vector<double> PdxReaderWithTypeCollector::readDoubleArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::DOUBLE_ARRAY, "double[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "double[]",
                                           PdxFieldTypes::DOUBLE_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readDoubleArray():position = %d",
           position);
  std::vector<double> doubleArrptr;
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    doubleArrptr = PdxLocalReader::readDoubleArray(fieldName);
    auto strSize =m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
  }
  return doubleArrptr;
}

std::vector<std::string> PdxReaderWithTypeCollector::readStringArray(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::STRING_ARRAY, "String[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "String[]",
                                           PdxFieldTypes::STRING_ARRAY);
  auto position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                              m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readStringArray(): position = %d",
           position);

  std::vector<std::string> value;

  if (position > 0) {
    m_dataInput->advanceCursor(position);
    auto startLoc = m_dataInput->currentBufferPosition();
    value = PdxLocalReader::readStringArray(fieldName);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(static_cast<int32_t>(strSize + position));
  }

  return value;
}

std::shared_ptr<CacheableObjectArray>
PdxReaderWithTypeCollector::readObjectArray(const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::OBJECT_ARRAY, "Object[]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "Object[]",
                                           PdxFieldTypes::OBJECT_ARRAY);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readObjectArray():position = %d",
           position);
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
   auto retVal = PdxLocalReader::readObjectArray(fieldName);
   auto strSize = m_dataInput->currentBufferPosition() - startLoc;
   m_dataInput->rewindCursor(strSize + position);
   startLoc = nullptr;
   return retVal;
  } else {
    return nullptr;
  }
}

int8_t** PdxReaderWithTypeCollector::readArrayOfByteArrays(
    const std::string& fieldName, int32_t& arrayLength,
    int32_t** elementLength) {
  checkType(fieldName, PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS, "byte[][]");
  m_newPdxType->addVariableLengthTypeField(fieldName, "byte[][]",
                                           PdxFieldTypes::ARRAY_OF_BYTE_ARRAYS);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readArrayOfByteArrays() position = %d",
           position);
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    const uint8_t* startLoc = m_dataInput->currentBufferPosition();
    int8_t** retVal = PdxLocalReader::readArrayOfByteArrays(
        fieldName, arrayLength, elementLength);
    auto strSize = m_dataInput->currentBufferPosition() - startLoc;
    m_dataInput->rewindCursor(strSize + position);
    startLoc = nullptr;
    return retVal;
  } else {
    return nullptr;
  }
}

std::shared_ptr<CacheableDate> PdxReaderWithTypeCollector::readDate(
    const std::string& fieldName) {
  checkType(fieldName, PdxFieldTypes::DATE, "Date");
  m_newPdxType->addFixedLengthTypeField(fieldName, "Date", PdxFieldTypes::DATE,
                                        PdxTypes::DATE_SIZE);
  int position = m_pdxType->getFieldPosition(fieldName, m_offsetsBuffer,
                                             m_offsetSize, m_serializedLength);
  LOGDEBUG("PdxReaderWithTypeCollector::readDate() position = %d", position);
  if (position != -1) {
    m_dataInput->advanceCursor(position);
    auto retVal = PdxLocalReader::readDate(fieldName);
    m_dataInput->rewindCursor(position + PdxTypes::DATE_SIZE);
    return retVal;
  } else {
    return nullptr;
  }
}

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