/*
 * 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_CACHEABLEENUM_H_
#define GEODE_CACHEABLEENUM_H_

#include <iosfwd>
#include <memory>
#include <string>

#include "CacheableKey.hpp"
#include "CacheableString.hpp"
#include "internal/geode_base.hpp"

namespace apache {
namespace geode {
namespace client {

class DataInput;
class DataOutput;
class Serializable;

/**
 * Since C++ enums cannot be directly passed as a parameter to PdxWriter's
 * writeObject and PdxReader's readObject api,
 * wrap C++ enums with an immutable wrapper CacheableEnum class type by
 * specifying enum class name, enum value name and its ordinal. C++ enum allows
 * explicit setting of ordinal number, but it is up to the user to map java
 * enumName with that of C++ enumName. Currently this wrapper only works as part
 * of PdxSerializable member object and cannot be directly used in Region
 * operations.
 *
 * @see PdxWriter#writeObject
 * @see PdxReader#readObject
 */

class APACHE_GEODE_EXPORT CacheableEnum
    : public internal::DataSerializablePrimitive,
      public CacheableKey {
 private:
  std::string m_enumClassName;
  std::string m_enumName;
  int32_t m_ordinal;
  int32_t m_hashcode;

 public:
  inline CacheableEnum()
      : m_enumClassName(nullptr),
        m_enumName(nullptr),
        m_ordinal(-1),
        m_hashcode(0) {}
  inline CacheableEnum(std::string enumClassName, std::string enumName,
                       int32_t ordinal)
      : m_enumClassName(std::move(enumClassName)),
        m_enumName(std::move(enumName)),
        m_ordinal(ordinal),
        m_hashcode(0) {}
  ~CacheableEnum() noexcept override = default;
  void operator=(const CacheableEnum& other) = delete;
  CacheableEnum(const CacheableEnum& other) = delete;

  /**
   * @brief creation function for enum.
   */
  static std::shared_ptr<Serializable> createDeserializable() {
    return std::make_shared<CacheableEnum>();
  }

  void toData(DataOutput& output) const override;

  virtual void fromData(DataInput& input) override;

  virtual size_t objectSize() const override {
    auto size = sizeof(CacheableEnum);
    size += m_enumClassName.length();
    size += m_enumName.length();
    return size;
  }

  virtual DSCode getDsCode() const override { return DSCode::CacheableEnum; }

  /**
   * Display this object as c string.
   */
  virtual std::string toString() const override { return "CacheableEnum"; }

  /**
   * Factory method for creating an instance of CacheableEnum.
   * @param className the name of the enum class that maps to the java enum
   * type.
   * @param enumName the name of the enum constant that maps to the java enum
   * type.
   * @param ordinal the ordinal value of the enum constant that maps to the java
   * enum type.
   * @return a {@link CacheableEnum} representing C++ enum.
   */
  static std::shared_ptr<CacheableEnum> create(std::string enumClassName,
                                               std::string enumName,
                                               int32_t ordinal) {
    return std::make_shared<CacheableEnum>(enumClassName, enumName, ordinal);
  }

  /**@return enum class name. */
  const std::string& getEnumClassName() const { return m_enumClassName; }

  /**@return enum name. */
  const std::string& getEnumName() const { return m_enumName; }

  /**@return enum ordinal. */
  int32_t getEnumOrdinal() const { return m_ordinal; }

  /** @return the hashcode for this key. */
  virtual int32_t hashcode() const override { return m_hashcode; }

  /** @return true if this key matches other. */
  virtual bool operator==(const CacheableKey& other) const override;

 protected:
  void calculateHashcode();
};

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

#endif  // GEODE_CACHEABLEENUM_H_
