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

#include "PdxFieldType.hpp"

#include <geode/PdxFieldTypes.hpp>

#include "PdxTypes.hpp"

namespace apache {
namespace geode {
namespace client {

int32_t fixedTypeSizes[] = {
    PdxTypes::BOOLEAN_SIZE,  // BOOLEAN
    PdxTypes::BOOLEAN_SIZE,  // BYTE
    PdxTypes::CHAR_SIZE,     // CHAR
    PdxTypes::CHAR_SIZE,     // SHORT
    PdxTypes::INTEGER_SIZE,  // INT
    PdxTypes::LONG_SIZE,     // LONG
    PdxTypes::INTEGER_SIZE,  // FLOAT
    PdxTypes::LONG_SIZE,     // DOUBLE
    PdxTypes::DATE_SIZE,     // DATE
    -1,                      // STRING
    -1,                      // OBJECT
    -1,                      // BOOLEAN_ARRAY
    -1,                      // CHAR_ARRAY
    -1,                      // BYTE_ARRAY
    -1,                      // SHORT_ARRAY
    -1,                      // INT_ARRAY
    -1,                      // LONG_ARRAY
    -1,                      // FLOAT_ARRAY
    -1,                      // DOUBLE_ARRAY
    -1,                      // STRING_ARRAY
    -1,                      // OBJECT_ARRAY
    -1,                      // ARRAY_OF_BYTE_ARRAYS
};

PdxFieldType::PdxFieldType()
    : Serializable(),
      m_fieldName(),
      m_className(),
      m_typeId(PdxFieldTypes::UNKNOWN),
      m_sequenceId(0),
      m_isVariableLengthType(false),
      m_isIdentityField(false),
      m_fixedSize(0),
      m_varLenFieldIdx(0),
      m_vlOffsetIndex(0),
      m_relativeOffset(0) {}

PdxFieldType::PdxFieldType(std::string fieldName, std::string className,
                           PdxFieldTypes typeId, int32_t sequenceId,
                           bool isVariableLengthType, int32_t fixedSize,
                           int32_t varLenFieldIdx)
    : Serializable(),
      m_fieldName(fieldName),
      m_className(className),
      m_typeId(typeId),
      m_sequenceId(sequenceId),
      m_isVariableLengthType(isVariableLengthType),
      m_isIdentityField(false),
      m_fixedSize(fixedSize),
      m_varLenFieldIdx(varLenFieldIdx),
      m_vlOffsetIndex(0),
      m_relativeOffset(0) {}

void PdxFieldType::toData(DataOutput& output) const {
  output.writeString(m_fieldName);
  output.writeInt(m_sequenceId);
  output.writeInt(m_varLenFieldIdx);
  output.write(static_cast<int8_t>(m_typeId));

  output.writeInt(m_relativeOffset);
  output.writeInt(m_vlOffsetIndex);
  output.writeBoolean(m_isIdentityField);
}

void PdxFieldType::fromData(DataInput& input) {
  m_fieldName = input.readString();
  m_sequenceId = input.readInt32();
  m_varLenFieldIdx = input.readInt32();
  m_typeId = PdxFieldTypes(input.read());
  m_relativeOffset = input.readInt32();
  m_vlOffsetIndex = input.readInt32();
  m_isIdentityField = input.readBoolean();
  m_fixedSize = getFixedTypeSize();
  if (m_fixedSize != -1) {
    m_isVariableLengthType = false;
  } else {
    m_isVariableLengthType = true;
  }
}

bool PdxFieldType::equals(std::shared_ptr<PdxFieldType> otherObj) {
  if (otherObj == nullptr) return false;

  PdxFieldType* otherFieldType = dynamic_cast<PdxFieldType*>(otherObj.get());

  if (otherFieldType == nullptr) return false;

  if (otherFieldType == this) return true;

  if (otherFieldType->m_fieldName.compare(m_fieldName) == 0 &&
      otherFieldType->m_typeId == m_typeId) {
    return true;
  }

  return false;
}

int32_t PdxFieldType::getFixedTypeSize() const {
  int32_t result = -1;

  if (m_typeId != PdxFieldTypes::UNKNOWN) {
    result = fixedTypeSizes[static_cast<int32_t>(m_typeId)];
  }

  return result;
}

std::string PdxFieldType::toString() const {
  char stringBuf[1024];
  std::snprintf(stringBuf, 1024,
                " PdxFieldName=%s TypeId=%d VarLenFieldIdx=%d sequenceid=%d\n",
                this->m_fieldName.c_str(), static_cast<int>(this->m_typeId),
                this->m_varLenFieldIdx, this->m_sequenceId);
  return std::string(stringBuf);
}

bool PdxFieldType::operator==(const PdxFieldType& other) const {
  if (m_className != other.m_className) {
    return false;
  }

  if (m_fieldName != other.m_fieldName) {
    return false;
  }

  return true;
}

bool PdxFieldType::operator!=(const PdxFieldType& other) const {
  return !(*this == other);
}

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