/*
 * 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_PDXINSTANCEFACTORY_H_
#define GEODE_PDXINSTANCEFACTORY_H_

#include <map>

#include "PdxInstance.hpp"
#include "internal/geode_globals.hpp"
#include "CacheableBuiltins.hpp"
#include "CacheableDate.hpp"
#include "CacheableObjectArray.hpp"

namespace apache {
namespace geode {
namespace client {

class PdxType;
typedef std::map<std::string, std::shared_ptr<Cacheable>> FieldVsValues;
class CachePerfStats;
class PdxTypeRegistry;
class AuthenticatedView;

/**
 * PdxInstanceFactory gives you a way to create PdxInstances.
 * Call the write methods to populate the field data and then call {@link
 * #create}
 * to produce an actual instance that contains the data.
 * To create a factory call {@link Cache#createPdxInstanceFactory}
 * A factory can only create a single instance. To create multiple instances
 * create
 * multiple factories or use {@link PdxInstance#createWriter} to create
 * subsequent instances.
 */
class APACHE_GEODE_EXPORT PdxInstanceFactory {
 public:
  PdxInstanceFactory() = delete;
  ~PdxInstanceFactory() noexcept = default;
  PdxInstanceFactory(const PdxInstanceFactory& other) = default;
  PdxInstanceFactory& operator=(const PdxInstanceFactory& other) = default;
  PdxInstanceFactory(PdxInstanceFactory&& other) = default;
  PdxInstanceFactory& operator=(PdxInstanceFactory&& other) = default;

 public:
  /**
   * Create a {@link PdxInstance}. The instance
   * will contain any data written to this factory
   * using the write methods.
   * @return the created Pdxinstance
   * @throws IllegalStateException if called more than once
   */
  std::shared_ptr<PdxInstance> create();

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>char16_t</code>.
   * <p>Java char is mapped to C++ char16_t.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeChar(const std::string& fieldName, char16_t value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>char</code>.
   * <p>Java char is mapped to C++ char.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeChar(const std::string& fieldName, char value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>bool</code>.
   * <p>Java boolean is mapped to C++ bool.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeBoolean(const std::string& fieldName, bool value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int8_t</code>.
   * <p>Java byte is mapped to C++ int8_t</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeByte(const std::string& fieldName, int8_t value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int16_t</code>.
   * <p>Java short is mapped to C++ int16_t.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeShort(const std::string& fieldName, int16_t value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int32_t</code>.
   * <p>Java int is mapped to C++ int32_t.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeInt(const std::string& fieldName, int32_t value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int64_t</code>.
   * <p>Java long is mapped to C++ int64_t.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeLong(const std::string& fieldName, int64_t value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>float</code>.
   * <p>Java float is mapped to C++ float.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeFloat(const std::string& fieldName, float value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>double</code>.
   * <p>Java double is mapped to C++ double.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeDouble(const std::string& fieldName, double value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>CacheableDatePtr</code>.
   * <p>Java Date is mapped to C++ std::shared_ptr<CacheableDate>.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeDate(const std::string& fieldName,
                                std::shared_ptr<CacheableDate> value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>std::string</code>.
   * <p>Java String is mapped to C++ std::string.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeString(const std::string& fieldName,
                                  const std::string& value);

  PdxInstanceFactory& writeString(const std::string& fieldName,
                                  std::string&& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>CacheablePtr</code>.
   * <p>Java object is mapped to C++ std::shared_ptr<Cacheable>.</p>
   * It is best to use one of the other writeXXX methods if your field type
   * will always be XXX. This method allows the field value to be anything
   * that is an instance of Object. This gives you more flexibility but more
   * space is used to store the serialized field.
   *
   * Note that some Java objects serialized with this method may not be
   * compatible with non-java languages.
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeObject(const std::string& fieldName,
                                  std::shared_ptr<Cacheable> value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>bool*</code>.
   * <p>Java boolean[] is mapped to C++ bool*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeBooleanArray(const std::string& fieldName,
                                        const std::vector<bool>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>char16_t*</code>.
   * <p>Java char[] is mapped to C++ char16_t*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeCharArray(const std::string& fieldName,
                                     const std::vector<char16_t>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int8_t*</code>.
   * <p>Java byte[] is mapped to C++ int8_t*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeByteArray(const std::string& fieldName,
                                     const std::vector<int8_t>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int16_t*</code>.
   * <p>Java short[] is mapped to C++ int16_t*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeShortArray(const std::string& fieldName,
                                      const std::vector<int16_t>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int32_t*</code>.
   * <p>Java int[] is mapped to C++ int32_t*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeIntArray(const std::string& fieldName,
                                    const std::vector<int32_t>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int64_t*</code>.
   * <p>Java long[] is mapped to C++ int64_t*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeLongArray(const std::string& fieldName,
                                     const std::vector<int64_t>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>float*</code>.
   * <p>Java float[] is mapped to C++ float*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeFloatArray(const std::string& fieldName,
                                      const std::vector<float>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>double*</code>.
   * <p>Java double[] is mapped to C++ double*.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeDoubleArray(const std::string& fieldName,
                                       const std::vector<double>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>char**</code>.
   * <p>Java String[] is mapped to C++ char**.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param length the length of the array field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeStringArray(const std::string& fieldName,
                                       const std::vector<std::string>& value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>CacheableObjectArrayPtr</code>.
   * Java Object[] is mapped to C++ std::shared_ptr<CacheableObjectArray>.
   * For how each element of the array is a mapped to C++ see {@link
   * #writeObject}.
   * Note that this call may serialize elements that are not compatible with
   * non-java languages.
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeObjectArray(
      const std::string& fieldName,
      std::shared_ptr<CacheableObjectArray> value);

  /**
   * Writes the named field with the given value to the serialized form.
   * The fields type is <code>int8_t**</code>.
   * <p>Java byte[][] is mapped to C++ int8_t**.</p>
   * @param fieldName the name of the field to write
   * @param value the value of the field to write
   * @param arrayLength the length of the actual byte array field holding
   * individual byte arrays to write
   * @param elementLength the length of the individual byte arrays to write
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field has already been written
   * or fieldName is nullptr or empty.
   */
  PdxInstanceFactory& writeArrayOfByteArrays(const std::string& fieldName,
                                             int8_t** value,
                                             int32_t arrayLength,
                                             int32_t* elementLength);

  /**
   * Indicate that the named field should be included in hashCode and equals
   * (operator==()) checks
   * of this object on a server that is accessing {@link PdxInstance}
   * or when a client executes a query on a server.
   *
   * The fields that are marked as identity fields are used to generate the
   * hashCode and
   * equals (operator==()) methods of {@link PdxInstance}. Because of this, the
   * identity fields should themselves
   * either be primitives, or implement hashCode and equals (operator==()).
   *
   * If no fields are set as identity fields, then all fields will be used in
   * hashCode and equals (operator==())
   * checks.
   *
   * The identity fields should make marked after they are written using a
   * write* method.
   *
   * @param fieldName the name of the field to mark as an identity field.
   * @return this PdxInstanceFactory
   * @throws IllegalStateException if the named field does not exist.
   */
  PdxInstanceFactory& markIdentityField(const std::string& fieldName);

 private:
  bool m_created;
  std::shared_ptr<PdxType> m_pdxType;
  FieldVsValues m_FieldVsValues;
  CachePerfStats& m_cachePerfStats;
  PdxTypeRegistry& m_pdxTypeRegistry;
  const CacheImpl& m_cacheImpl;
  bool m_enableTimeStatistics;
  void isFieldAdded(const std::string& fieldName);

  PdxInstanceFactory(const std::string& className,
                     CachePerfStats& cachePerfStats,
                     PdxTypeRegistry& m_pdxTypeRegistry, const CacheImpl& cache,
                     bool enableTimeStatistics);

  friend CacheImpl;
  friend AuthenticatedView;
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_PDXINSTANCEFACTORY_H_
