/*
 * 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_REGION_H_
#define GEODE_REGION_H_

#include <chrono>
#include <iosfwd>
#include <memory>

#include "AttributesMutator.hpp"
#include "CacheListener.hpp"
#include "CacheLoader.hpp"
#include "CacheStatistics.hpp"
#include "CacheWriter.hpp"
#include "CacheableBuiltins.hpp"
#include "CacheableKey.hpp"
#include "CacheableString.hpp"
#include "ExceptionTypes.hpp"
#include "PartitionResolver.hpp"
#include "Query.hpp"
#include "RegionAttributes.hpp"
#include "RegionAttributesFactory.hpp"
#include "RegionEntry.hpp"
#include "Serializable.hpp"
#include "internal/geode_globals.hpp"

namespace apache {
namespace geode {
namespace client {

class Pool;
class AttributesMutator;
class Cache;
class CacheStatistics;
class CacheableKey;
class RegionAttributes;
class RegionEntry;
class RegionService;
class SelectResults;
class Serializable;

static constexpr std::chrono::milliseconds DEFAULT_RESPONSE_TIMEOUT =
    std::chrono::seconds(15);

/**
 * @class Region Region.hpp
 *
 * This class manages subregions and cached data. Each region
 * can contain multiple subregions and entries for data.
 * Regions provide a hierachical name space
 * within the cache. Also, a region can be used to group cached
 * objects for management purposes.
 *
 * Entries managed by the region are key-value pairs. A set of region attributes
 * is associated with the region when it is created.
 *
 * The Region interface basically contains two set of APIs: Region management
 * APIs and (potentially) distributed operations on entries. Non-distributed
 * operations on entries  are provided by <code>RegionEntry</code>.
 *
 * Each <code>Cache</code> defines regions called the root regions.
 * User applications can use the root regions to create subregions
 * for isolated name space and object grouping.
 *
 * A region's name can be any String, except that it should not contain
 * the region name separator, a forward slash (/).
 *
 * <code>Regions</code>  can be referenced by a relative path name from any
 * region
 * higher in the hierarchy in {@link Region::getSubregion}. You can get the
 * relative
 * path from the root region with {@link Region::getFullPath}. The name
 * separator is used to concatenate all the region names together from the root,
 * starting with the root's subregions.
 *
 * @see RegionAttributes
 */
class APACHE_GEODE_EXPORT Region : public std::enable_shared_from_this<Region> {
  /** @brief Public Methods
   */
 public:
  /** return single name of region. The storage is backed by the region. */
  virtual const std::string& getName() const = 0;
  // virtual uint64_t getUpdateReceived() const { return 0; };

  /** return the full path of the region as can be used to lookup the
   * region from Cache::getRegion. The storage is backed by the region.
   */
  virtual const std::string& getFullPath() const = 0;

  /** Returns the parent region, or nullptr if a root region.
   * @throws RegionDestroyedException
   */
  virtual std::shared_ptr<Region> getParentRegion() const = 0;

  /** Return the RegionAttributes for this region.
   */
  virtual const RegionAttributes& getAttributes() const = 0;

  /** Return the a mutator object for changing a subset of the region
   * attributes.
   * @throws RegionDestroyedException.
   */
  virtual std::shared_ptr<AttributesMutator> getAttributesMutator() const = 0;

  // virtual void updateAccessOrModifiedTime() = 0;

  virtual std::shared_ptr<CacheStatistics> getStatistics() const = 0;

  /** Invalidates this region. The invalidation will cascade to
   * all the subregions and cached entries. After
   * the <code>invalidateRegion</code> , the region and the entries in it still
   * exist. In order to remove all the entries and the region,
   * <code>destroyRegion</code> should be used.
   *
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this method. Can be nullptr. If it is sent on the wire,
   * it has to be Serializable.
   * @throws CacheListenerException if CacheListener throws an exception; if
   * this occurs some subregions may have already been successfully invalidated
   * @throws RegionDestroyedException if the region is no longer valid
   * @see   destroyRegion
   * @see   CacheListener::afterRegionInvalidate
   * This operation is not distributed.
   */
  virtual void invalidateRegion(
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Invalidates this region. The invalidation will cascade to
  * all the subregions and cached entries. After
  * the <code>invalidateRegion</code> , the region and the entries in it still
  * exist. In order to remove all the entries and the region,
  * <code>destroyRegion</code> should be used. The region invalidate will not be
  distributed
  * to other caches
  *
  * @param aCallbackArgument a user-defined parameter to pass to callback events
  *        triggered by this method.
  *        Can be nullptr. If it is sent on the wire, it has to be Serializable.
  * @throws CacheListenerException if CacheListener throws an exception; if this
  *         occurs some subregions may have already been successfully
  invalidated
  * @throws RegionDestroyedException if the region is no longer valid
  * @see   destroyRegion
  * @see   CacheListener::afterRegionInvalidate

  */
  virtual void localInvalidateRegion(
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Destroys the whole region and provides a user-defined parameter
   * object to any <code>CacheWriter</code> invoked in the process.
   * Destroy cascades to all entries
   * and subregions. After the destroy, this region object cannot be used
   * any more. Any attempt to use this region object will get a
   * <code>RegionDestroyedException</code> exception.
   *
   * The region destroy not only destroys the local region but also destroys the
   * server region. However, if server region destroy fails throwing back
   * <code>CacheServerException</code> or security exception,
   * the local region is still destroyed.
   *
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this call. Can be nullptr. If it is sent on the wire,
   * it has to be Serializable.
   * @throws CacheWriterException if CacheWriter aborts the operation; if this
   *         occurs some subregions may have already been successfully
   * destroyed.
   * @throws CacheListenerException if CacheListener throws an exception; if
   * this occurs some subregions may have already been successfully invalidated
   * @throws CacheServerException If an exception is received from the Java
   * cache server. Only for Native Client regions.
   * @throws NotConnectedException if not connected to the geode system because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it.
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if operation timed out
   * @see  invalidateRegion
   */
  virtual void destroyRegion(
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;
  /**
   * Removes all entries from this region and provides a user-defined parameter
   * object to any <code>CacheWriter</code> or <code>CacheListener</code>
   * invoked in the process.
   * @see CacheListener#afterRegionClear
   * @see CacheWriter#beforeRegionClear
   */
  virtual void clear(
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;
  /**
   * Removes all entries from this region and provides a user-defined parameter
   * object to any <code>CacheWriter</code> or <code>CacheListener</code>
   * invoked in the process. Clear will not be distributed to other caches.
   * @see CacheListener#afterRegionClear
   * @see CacheWriter#beforeRegionClear
   */
  virtual void localClear(
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Destroys the whole region and provides a user-defined parameter
   * object to any <code>CacheWriter</code> invoked in the process.
   * Destroy cascades to all entries
   * and subregions. After the destroy, this region object cannot be used
   * any more. Any attempt to use this region object will get a
   * <code>RegionDestroyedException</code> exception. The region destroy is not
   * distributed to other caches.
   *
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this call. Can be nullptr. If it is sent on the wire,
   * it has to be Serializable.
   * @throws CacheWriterException if CacheWriter aborts the operation; if this
   *         occurs some subregions may have already been successfully
   * destroyed.
   * @throws CacheListenerException if CacheListener throws an exception; if
   * this occurs some subregions may have already been successfully invalidated
   *
   * @see  localInvalidateRegion
   */
  virtual void localDestroyRegion(
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Returns the subregion identified by the path, nullptr if no such subregion
   */
  virtual std::shared_ptr<Region> getSubregion(const std::string& path) = 0;

  /** Creates a subregion with the specified attributes */
  virtual std::shared_ptr<Region> createSubregion(
      const std::string& subregionName, RegionAttributes aRegionAttributes) = 0;

  /** Populates the passed in std::vector<std::shared_ptr<Region>> with
   * subregions of the current region
   * @param recursive determines whether the method recursively fills in
   * subregions
   * @throws RegionDestroyedException
   */
  virtual std::vector<std::shared_ptr<Region>> subregions(
      const bool recursive) = 0;

  /** Return the meta-object RegionEntry for key.
   * @throws IllegalArgumentException, RegionDestroyedException.
   */
  virtual std::shared_ptr<RegionEntry> getEntry(
      const std::shared_ptr<CacheableKey>& key) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline std::shared_ptr<RegionEntry> getEntry(const KEYTYPE& key) {
    return getEntry(CacheableKey::create(key));
  }

  /** Returns the value associated with the specified key, passing the callback
   * argument to any cache loaders that are invoked in the
   * operation.
   * If the value is not present locally then it is requested from the java
   *server.
   * If even that is unsuccessful then a local CacheLoader will be invoked if
   *there is one.
   * The value returned by get is not copied, so multi-threaded applications
   * should not modify the value directly, but should use the update methods.
   *<p>
   * Updates the {@link CacheStatistics::getLastAccessedTime},
   * {@link CacheStatistics::getHitCount}, {@link
   *CacheStatistics::getMissCount}, and {@link
   *CacheStatistics::getLastModifiedTime} (if a new value is loaded) for this
   *region and the entry.
   *
   * @param key whose associated value is to be returned. The key Object must
   * implement the equals and hashCode methods.
   * @param aCallbackArgument an argument passed into the CacheLoader if
   * loader is used. If it is sent on the wire, it has to be Serializable.
   *
   * @throws IllegalArgumentException if key is nullptr or aCallbackArgument is
   *         not serializable and a remote CacheLoader needs to be invoked
   * @throws CacheLoaderException if CacheLoader throws an exception
   * @throws CacheServerException If an exception is received from the Java
   *cache server. Only for Native Client regions.
   * @throws NotConnectedException if it is not connected to the cache because
   *the client
   *         cannot establish usable connections to any of the servers given to
   *it.
   *         For pools configured with locators, if no locators are available,
   *the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if operation timed out
   * @throws RegionDestroyedException if the method is called on a destroyed
   *region
   **/
  virtual std::shared_ptr<Cacheable> get(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline std::shared_ptr<Cacheable> get(
      const KEYTYPE& key,
      const std::shared_ptr<Serializable>& callbackArg = nullptr) {
    return get(CacheableKey::create(key), callbackArg);
  }

  /** Places a new value into an entry in this region with the specified key,
   * providing a user-defined parameter
   * object to any <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * If there is already an entry associated with the specified key in this
   * region,
   * the entry's previous value is overwritten.
   * The new put value is propogated to the java server to which it is connected
   * with.
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   *
   * If remote server put fails throwing back a
   * <code>CacheServerException</code> or security exception, then local put is
   * tried to rollback. However, if the entry has overflowed/evicted/expired
   * then the rollback is aborted since it may be due to a more recent
   * notification or update by another thread.
   *
   * @param key a key smart pointer associated with the value to be put into
   * this region.
   * @param value the value to be put into the cache
   * @param aCallbackArgument an argument that is passed to the callback
   * function
   *
   * @throws IllegalArgumentException if key or value is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws RegionDestroyedException if region no longer valid
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if operation timed out
   * @throws OutOfMemoryException if  not enoough memory for the value
   */
  virtual void put(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing both key and value to be a const char* */
  template <class KEYTYPE, class VALUETYPE>
  inline void put(const KEYTYPE& key, const VALUETYPE& value,
                  const std::shared_ptr<Serializable>& arg = nullptr) {
    put(CacheableKey::create(key), Serializable::create(value), arg);
  }

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void put(const KEYTYPE& key, const std::shared_ptr<Cacheable>& value,
                  const std::shared_ptr<Serializable>& arg = nullptr) {
    put(CacheableKey::create(key), value, arg);
  }

  /** Convenience method allowing value to be a const char* */
  template <class VALUETYPE>
  inline void put(const std::shared_ptr<CacheableKey>& key,
                  const VALUETYPE& value,
                  const std::shared_ptr<Serializable>& arg = nullptr) {
    put(key, Serializable::create(value), arg);
  }

  /**
   * Places a set of new values in this region with the specified keys
   * given as a map of key/value pairs.
   * If there is already an entry associated with a specified key in this
   * region, the entry's previous value is overwritten.
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and
   * the entries.
   *
   * @param map: A hashmap containing key-value pairs
   * @param timeout: The time to wait for the response, optional.
   * @param aCallbackArgument an argument that is passed to the callback
   * functions.
   * It is ignored if nullptr. It must be serializable if this operation is
   * distributed.
   * @throws IllegalArgumentException If timeout exceeds 2147483647ms.
   * @since 8.1
   */
  virtual void putAll(
      const HashMapOfCacheable& map,
      std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /**
   * Places a new value into an entry in this region with the specified key
   * in the local cache only, providing a user-defined parameter
   * object to any <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * If there is already an entry associated with the specified key in this
   * region,
   * the entry's previous value is overwritten.
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   *
   * @param key a key smart pointer associated with the value to be put into
   * this region.
   * @param value the value to be put into the cache
   * @param aCallbackArgument an argument that is passed to the callback
   * functions
   *
   * @throws IllegalArgumentException if key or value is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws RegionDestroyedException if region no longer valid
   * @throws OutOfMemoryException if not enoough memory for the value
   */
  virtual void localPut(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing both key and value to be a const char* */
  template <class KEYTYPE, class VALUETYPE>
  inline void localPut(const KEYTYPE& key, const VALUETYPE& value,
                       const std::shared_ptr<Serializable>& arg = nullptr) {
    localPut(CacheableKey::create(key), Serializable::create(value), arg);
  }

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void localPut(const KEYTYPE& key,
                       const std::shared_ptr<Cacheable>& value,
                       const std::shared_ptr<Serializable>& arg = nullptr) {
    localPut(CacheableKey::create(key), value, arg);
  }

  /** Convenience method allowing value to be a const char* */
  template <class VALUETYPE>
  inline void localPut(const std::shared_ptr<CacheableKey>& key,
                       const VALUETYPE& value,
                       const std::shared_ptr<Serializable>& arg = nullptr) {
    localPut(key, Serializable::create(value), arg);
  }

  /** Creates a new entry in this region with the specified key and value,
   * providing a user-defined parameter
   * object to any <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * The new entry is propogated to the java server also to which it is
   * connected with. <p>Updates the {@link CacheStatistics::getLastAccessedTime}
   * and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * If remote server put fails throwing back a
   * <code>CacheServerException</code> or security exception, then local put is
   * tried to rollback. However, if the entry has overflowed/evicted/expired
   * then the rollback is aborted since it may be due to a more recent
   * notification or update by another thread.
   *
   * @param key the key smart pointer for which to create the entry in this
   * region.
   * @param value the value for the new entry, which may be nullptr meaning
   *              the new entry starts as if it had been locally invalidated.
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this method. Can be nullptr. Should be serializable if
   *        passed to remote callback events
   * @throws IllegalArgumentException if key is nullptr or if the key, value, or
   *         aCallbackArgument do not meet serializability requirements
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws RegionDestroyedException if region is no longer valid
   * @throws CacheServerException If an exception is received from the Java
   * cache server. Only for Native Client regions.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if the operation timed out
   * @throws OutOfMemoryException if no memory for new entry
   * @throws EntryExistsException if an entry with this key already exists
   */
  virtual void create(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing both key and value to be a const char* */
  template <class KEYTYPE, class VALUETYPE>
  inline void create(const KEYTYPE& key, const VALUETYPE& value,
                     const std::shared_ptr<Serializable>& arg = nullptr) {
    create(CacheableKey::create(key), Serializable::create(value), arg);
  }

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void create(const KEYTYPE& key,
                     const std::shared_ptr<Cacheable>& value,
                     const std::shared_ptr<Serializable>& arg = nullptr) {
    create(CacheableKey::create(key), value, arg);
  }

  /** Convenience method allowing value to be a const char* */
  template <class VALUETYPE>
  inline void create(const std::shared_ptr<CacheableKey>& key,
                     const VALUETYPE& value,
                     const std::shared_ptr<Serializable>& arg = nullptr) {
    create(key, Serializable::create(value), arg);
  }

  /** Creates a new entry in this region with the specified key and value
   * in the local cache only, providing a user-defined parameter
   * object to any <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key smart pointer for which to create the entry in this
   * region.
   * @param value the value for the new entry, which may be nullptr meaning
   *              the new entry starts as if it had been locally invalidated.
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events
   *        triggered by this method. Can be nullptr. Should be serializable if
   *        passed to remote callback events
   *
   * @throws IllegalArgumentException if key or value is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws RegionDestroyedException if region is no longer valid
   * @throws OutOfMemoryException if no memory for new entry
   * @throws EntryExistsException if an entry with this key already exists
   */
  virtual void localCreate(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing both key and value to be a const char* */
  template <class KEYTYPE, class VALUETYPE>
  inline void localCreate(const KEYTYPE& key, const VALUETYPE& value,
                          const std::shared_ptr<Serializable>& arg = nullptr) {
    localCreate(CacheableKey::create(key), Serializable::create(value), arg);
  }

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void localCreate(const KEYTYPE& key,
                          const std::shared_ptr<Cacheable>& value,
                          const std::shared_ptr<Serializable>& arg = nullptr) {
    localCreate(CacheableKey::create(key), value, arg);
  }

  /** Convenience method allowing value to be a const char* */
  template <class VALUETYPE>
  inline void localCreate(const std::shared_ptr<CacheableKey>& key,
                          const VALUETYPE& value,
                          const std::shared_ptr<Serializable>& arg = nullptr) {
    localCreate(key, Serializable::create(value), arg);
  }

  /** Invalidates the entry with the specified key,
   * and provides a user-defined argument to the <code>CacheListener</code>.
   * Invalidate only removes the value from the entry, the key is kept intact.
   * To completely remove the entry, destroy should be used.
   * The invalidate is not propogated to the Geode cache server to which it is
   * connected with.
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the value to be invalidated
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this method. Can be nullptr. Should be serializable if
   *        passed to remote callback events
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws EntryNotFoundException if this entry does not exist in this region
   * locally
   * @throws RegionDestroyedException if the region is destroyed
   * @see destroy
   * @see CacheListener::afterInvalidate
   */
  virtual void invalidate(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void invalidate(const KEYTYPE& key,
                         const std::shared_ptr<Serializable>& arg = nullptr) {
    invalidate(CacheableKey::create(key), arg);
  }

  /** Invalidates the entry with the specified key in the local cache only,
   * and provides a user-defined argument to the <code>CacheListener</code>.
   * Invalidate only removes the value from the entry, the key is kept intact.
   * To completely remove the entry, destroy should be used.
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the value to be invalidated
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this method. Can be nullptr. Should be serializable if
   *        passed to remote callback events
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws EntryNotFoundException if this entry does not exist in this region
   * locally
   * @throws RegionDestroyedException if the region is destroyed
   * @see destroy
   * @see CacheListener::afterInvalidate
   */
  virtual void localInvalidate(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void localInvalidate(
      const KEYTYPE& key, const std::shared_ptr<Serializable>& arg = nullptr) {
    localInvalidate(CacheableKey::create(key), arg);
  }

  /** Destroys the entry with the specified key, and provides a user-defined
   * parameter object to any <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * Destroy removes
   * not only the value, but also the key and entry from this region.
   *
   * The destroy is propogated to the Geode cache server to which it is
   * connected with. If the destroy fails due to an exception on server
   * throwing back <code>CacheServerException</code> or security exception,
   * then the local entry is still destroyed.
   *
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the entry to destroy
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this method. Can be nullptr. If it is sent on the wire,
   * it has to be Serializable.
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws CacheServerException If an exception is received from the Geode
   * cache server.
   *         Only for Native Client regions.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if the operation timed out
   * @throws RegionDestroyedException if the region is destroyed.
   * @throws EntryNotFoundException if the entry does not exist in this region.
   * @see invalidate
   * @see CacheListener::afterDestroy
   * @see CacheWriter::beforeDestroy
   */
  virtual void destroy(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void destroy(const KEYTYPE& key,
                      const std::shared_ptr<Serializable>& arg = nullptr) {
    destroy(CacheableKey::create(key), arg);
  }

  /** Destroys the entry with the specified key in the local cache only,
   * and provides a user-defined parameter object to any
   * <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * Destroy removes
   * not only the value but also the key and entry from this region.
   * <p>
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the entry to destroy.
   * @param aCallbackArgument the callback for user to pass in, default is
   * nullptr.
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws EntryNotFoundException if the entry does not exist in this region
   * locally
   * @see invalidate
   * @see CacheListener::afterDestroy
   * @see CacheWriter::beforeDestroy
   */
  virtual void localDestroy(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline void localDestroy(const KEYTYPE& key,
                           const std::shared_ptr<Serializable>& arg = nullptr) {
    localDestroy(CacheableKey::create(key), arg);
  }

  /** Removes the entry with the specified key, value and provides a
   * user-defined
   * parameter object to any <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code> and
   * <code>CacheWriter</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * remove removes
   * not only the value, but also the key and entry from this region.
   *
   * The remove is propogated to the Geode cache server to which it is
   * connected with. If the destroy fails due to an exception on server
   * throwing back <code>CacheServerException</code> or security exception,
   * then the local entry is still removed.
   *
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the entry to remove
   * @param value the value of the key to remove, it can be nullptr.
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this method. Can be nullptr. If it is sent on the wire,
   * it has to be Serializable.
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws CacheServerException If an exception is received from the Geode
   * cache server.
   *         Only for Native Client regions.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if the operation timed out
   * @throws RegionDestroyedException if the region is destroyed.
   * @return the boolean true if an entry(key, value)has been removed or
   * false if an entry(key, value) has not been removed.
   * @see destroy
   * @see CacheListener::afterDestroy
   * @see CacheWriter::beforeDestroy
   */
  virtual bool remove(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing both key and value to be a const char* */
  template <class KEYTYPE, class VALUETYPE>
  inline bool remove(const KEYTYPE& key, const VALUETYPE& value,
                     const std::shared_ptr<Serializable>& arg = nullptr) {
    return remove(CacheableKey::create(key), Serializable::create(value), arg);
  }

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline bool remove(const KEYTYPE& key,
                     const std::shared_ptr<Cacheable>& value,
                     const std::shared_ptr<Serializable>& arg = nullptr) {
    return remove(CacheableKey::create(key), value, arg);
  }

  /** Convenience method allowing value to be a const char* */
  template <class VALUETYPE>
  inline bool remove(const std::shared_ptr<CacheableKey>& key,
                     const VALUETYPE& value,
                     const std::shared_ptr<Serializable>& arg = nullptr) {
    return remove(key, Serializable::create(value), arg);
  }

  bool remove(const std::shared_ptr<CacheableKey>& key) {
    return removeEx(key);
  }

  /** Convenience method allowing both key and value to be a const char* */
  template <class KEYTYPE>
  inline bool remove(const KEYTYPE& key) {
    return remove(CacheableKey::create(key));
  }

  /** Removes the entry with the specified key and provides a user-defined
   * parameter object to any <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code> and
   * <code>CacheWriter</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * remove removes
   * not only the value, but also the key and entry from this region.
   *
   * The remove is propogated to the Geode cache server to which it is
   * connected with. If the destroy fails due to an exception on server
   * throwing back <code>CacheServerException</code> or security exception,
   * then the local entry is still removed.
   *
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the entry to remove
   * @param aCallbackArgument a user-defined parameter to pass to callback
   * events triggered by this method. Can be nullptr. If it is sent on the wire,
   * it has to be Serializable.
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @throws CacheServerException If an exception is received from the Geode
   * cache server.
   *         Only for Native Client regions.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if the operation timed out
   * @throws RegionDestroyedException if the region is destroyed.
   * @return the boolean true if an entry(key, value)has been removed or
   * false if an entry(key, value) has not been removed.
   * @see destroy
   * @see CacheListener::afterDestroy
   * @see CacheWriter::beforeDestroy
   */
  virtual bool removeEx(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline bool removeEx(const KEYTYPE& key,
                       const std::shared_ptr<Serializable>& arg = nullptr) {
    return removeEx(CacheableKey::create(key), arg);
  }

  /** Removes the entry with the specified key and value in the local cache
   * only,
   * and provides a user-defined parameter object to any
   * <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code> and
   * <code>CacheWriter</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * Remove removes
   * not only the value but also the key and entry from this region.
   * <p>
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the entry to remove.
   * @param value the value of the entry to remove.
   * @param aCallbackArgument the callback for user to pass in, default is
   * nullptr.
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @return the boolean true if an entry(key, value)has been removed or
   * false if an entry(key, value) has not been removed.
   * @see destroy
   * @see CacheListener::afterDestroy
   * @see CacheWriter::beforeDestroy
   */
  virtual bool localRemove(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing both key and value to be a const char* */
  template <class KEYTYPE, class VALUETYPE>
  inline bool localRemove(const KEYTYPE& key, const VALUETYPE& value,
                          const std::shared_ptr<Serializable>& arg = nullptr) {
    return localRemove(CacheableKey::create(key), Serializable::create(value),
                       arg);
  }

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline bool localRemove(const KEYTYPE& key,
                          const std::shared_ptr<Cacheable>& value,
                          const std::shared_ptr<Serializable>& arg = nullptr) {
    return localRemove(CacheableKey::create(key), value, arg);
  }

  /** Convenience method allowing value to be a const char* */
  template <class VALUETYPE>
  inline bool localRemove(const std::shared_ptr<CacheableKey>& key,
                          const VALUETYPE& value,
                          const std::shared_ptr<Serializable>& arg = nullptr) {
    return localRemove(key, Serializable::create(value), arg);
  }

  /** Removes the entry with the specified key in the local cache only,
   * and provides a user-defined parameter object to any
   * <code>CacheWriter</code> invoked in the process.
   * The same parameter is also passed to the <code>CacheListener</code> and
   * <code>CacheWriter</code>,
   * if one is defined for this <code>Region</code>, invoked in the process.
   * Remove removes
   * not only the value but also the key and entry from this region.
   * <p>
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and the entry.
   * <p>
   *
   * @param key the key of the entry to remove.
   * @param aCallbackArgument the callback for user to pass in, default is
   * nullptr.
   * @throws IllegalArgumentException if key is nullptr
   * @throws CacheWriterException if CacheWriter aborts the operation
   * @throws CacheListenerException if CacheListener throws an exception
   * @return the boolean true if an entry(key, value)has been removed or
   * false if an entry(key, value) has not been removed.
   * @see destroy
   * @see CacheListener::afterDestroy
   * @see CacheWriter::beforeDestroy
   */

  virtual bool localRemoveEx(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /** Convenience method allowing key to be a const char* */
  template <class KEYTYPE>
  inline bool localRemoveEx(
      const KEYTYPE& key, const std::shared_ptr<Serializable>& arg = nullptr) {
    return localRemoveEx(CacheableKey::create(key), arg);
  }

  /**
   * Return all the keys in the local process for this region. This includes
   * keys for which the entry is invalid.
   */
  virtual std::vector<std::shared_ptr<CacheableKey>> keys() = 0;

  /**
   * Return the set of keys defined in the server process associated to this
   * client and region. If a server has the region defined as a mirror, then
   * this will be the entire keyset for the region across all PEER in the
   * distributed system.
   * The vector v will contain only the server keys. Any prior contents in the
   * vector will be removed.
   * @throws CacheServerException If an exception is received from the Geode
   * cache server.
   *         Only for Native Client regions.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if there is a timeout getting the keys
   * @throws UnsupportedOperationException if the member type is not CLIENT
   *                                       or region is not a native client one.
   */
  virtual std::vector<std::shared_ptr<CacheableKey>> serverKeys() = 0;

  /**
   * Return all values in the local process for this region. No value is
   * included for entries that are invalidated.
   */
  virtual std::vector<std::shared_ptr<Cacheable>> values() = 0;

  virtual std::vector<std::shared_ptr<RegionEntry>> entries(bool recursive) = 0;

  /**
   * Returns the <code>cache</code> associated with this region.
   * @return the cache
   */
  virtual RegionService& getRegionService() const = 0;

  virtual bool isDestroyed() const = 0;

  /**
   * This operations checks for the value in the local cache .
   * It is not propagated to the Geode cache server
   * to which it is connected.
   */
  virtual bool containsValueForKey(
      const std::shared_ptr<CacheableKey>& keyPtr) const = 0;

  /**
   * Convenience method allowing key to be a const char*
   * This operations checks for the value in the local cache .
   * It is not propagated to the Geode cache server
   * to which it is connected.
   */
  template <class KEYTYPE>
  inline bool containsValueForKey(const KEYTYPE& key) const {
    return containsValueForKey(CacheableKey::create(key));
  }

  /**
   * Only the client's cache is searched for the key. It does not go to the java
   * server
   * to which it is connected with.
   */
  virtual bool containsKey(
      const std::shared_ptr<CacheableKey>& keyPtr) const = 0;
  /**
   * The cache of the server, to which it is connected with, is searched
   * for the key to see if the key is present.
   * @throws UnsupportedOperationException if the region's scope is
   * ScopeType::LOCAL.
   */
  virtual bool containsKeyOnServer(
      const std::shared_ptr<CacheableKey>& keyPtr) const = 0;
  /**
   * Returns the list of keys on which this client is interested and will be
   * notified of changes.
   * @throws UnsupportedOperationException if the region's scope is
   * ScopeType::LOCAL.
   */
  virtual std::vector<std::shared_ptr<CacheableKey>> getInterestList()
      const = 0;
  /**
   * Returns the list of regular expresssions on which this client is
   * interested and will be notified of changes.
   * @throws UnsupportedOperationException if the region's scope is
   * ScopeType::LOCAL.
   */
  virtual std::vector<std::shared_ptr<CacheableString>> getInterestListRegex()
      const = 0;
  /**
   * Convenience method allowing key to be a const char*
   * This operations checks for the key in the local cache .
   * It is not propagated to the Geode cache server
   * to which it is connected.
   */
  template <class KEYTYPE>
  inline bool containsKey(const KEYTYPE& key) const {
    return containsKey(CacheableKey::create(key));
  }

  /**
   * Registers an array of keys for getting updates from the server.
   *
   * @param keys the array of keys
   * @param isDurable flag to indicate whether this is a durable registration
   * @param getInitialValues true to populate the cache with values of the keys
   *   that were registered on the server
   * @param receiveValues whether to act like notify-by-subscription is set
   *
   * @throws IllegalArgumentException If the array of keys is empty.
   * @throws IllegalStateException If already registered interest for all keys.
   * @throws EntryNotFoundException If an exception occurs while obtaining
   *   values from server after register interest is complete. The actual cause
   *   of the exception can be obtained using <code>Exception::getCause</code>.
   *   If an application wants to undo the registration on server, or take
   *   some other steps for the incomplete cache population then this is
   *   the exception that should be caught.
   * @throws UnsupportedOperationException If the region is not a Native Client
   * region
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws UnknownException For other exceptions.
   * @throws TimeoutException if operation timed out
   */
  virtual void registerKeys(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      bool isDurable = false, bool getInitialValues = false,
      bool receiveValues = true) = 0;

  /**
   * Unregisters an array of keys to stop getting updates for them.
   *
   * @param keys the array of keys
   *
   * @throws IllegalArgumentException If the array of keys is empty.
   * @throws IllegalStateException If no keys were previously registered.
   * @throws UnsupportedOperationException If the region is not a Native Client
   * region
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws UnknownException For other exceptions.
   * @throws TimeoutException if operation timed out
   */
  virtual void unregisterKeys(
      const std::vector<std::shared_ptr<CacheableKey>>& keys) = 0;

  /**
   * Registers to get updates for all keys from the server.
   *
   * @param isDurable flag to indicate whether this is a durable registration
   * @param getInitialValues true to populate the cache with values of all keys
   *   from the server
   * @param receiveValues whether to act like notify-by-subscription is set
   *
   * @throws EntryNotFoundException If an exception occurs while obtaining
   *   values from server after register interest is complete. The actual cause
   *   of the exception can be obtained using <code>Exception::getCause</code>.
   *   If an application wants to undo the registration on server, or take
   *   some other steps for the incomplete cache population then this is
   *   the exception that should be caught.
   * @throws UnsupportedOperationException If the region is not a Native Client
   * region
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws UnknownException For other exceptions.
   * @throws TimeoutException if operation timed out
   */
  virtual void registerAllKeys(bool isDurable = false,
                               bool getInitialValues = false,
                               bool receiveValues = true) = 0;

  /**
   * Registers to get updates for all keys from the server.
   *
   * @throws IllegalStateException If not previously registered all keys.
   * @throws UnsupportedOperationException If the region is not a Native Client
   * region
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws UnknownException For other exceptions.
   * @throws TimeoutException if operation timed out
   */
  virtual void unregisterAllKeys() = 0;

  /**
   * Registers a regular expression to match with keys to get updates from the
   * server.
   *
   * @param regex The regular expression string.
   * @param isDurable flag to indicate whether this is a durable registration
   * @param getInitialValues true to populate the cache with values of the keys
   *   that were registered on the server
   * @param receiveValues whether to act like notify-by-subscription is set
   *
   * @throws IllegalArgumentException If regex is empty.
   * @throws IllegalStateException If already registered interest for all keys.
   * @throws EntryNotFoundException If an exception occurs while obtaining
   *   values from server after register interest is complete. The actual cause
   *   of the exception can be obtained using <code>Exception::getCause</code>.
   *   If an application wants to undo the registration on server, or take
   *   some other steps for the incomplete cache population then this is
   *   the exception that should be caught.
   * @throws UnsupportedOperationException If the region is not a Native Client
   * region
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws UnknownException For other exceptions.
   * @throws TimeoutException if operation timed out
   */
  virtual void registerRegex(const std::string& regex, bool isDurable = false,
                             bool getInitialValues = false,
                             bool receiveValues = true) = 0;

  /**
   * Unregisters a regular expression to stop getting updates for keys from the
   * server.
   *
   * @param regex The regular expression string.
   *
   * @throws IllegalArgumentException If regex is empty.
   * @throws IllegalStateException If not previously registered this regular
   * expression string.
   * @throws UnsupportedOperationException If the region is not a Native Client
   * region
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if it is not connected to the cache because
   * the client
   *         cannot establish usable connections to any of the servers given to
   * it
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws UnknownException For other exceptions.
   * @throws TimeoutException if operation timed out
   */
  virtual void unregisterRegex(const std::string& regex) = 0;

  /**
   * Gets values for an array of keys from the local cache or server.
   * If value for a key is not present locally then it is requested from the
   * java server. The value returned is not copied, so multi-threaded
   * applications should not modify the value directly,
   * but should use the update methods.
   *<p>
   * Updates the {@link CacheStatistics::getLastAccessedTime},
   * {@link CacheStatistics::getHitCount} and {@link
   *CacheStatistics::getMissCount}
   * for this region and the entry.
   *
   * @param keys the array of keys
   * @param values Output parameter that provides the map of keys to
   *   respective values. It is ignored if nullptr, and when nullptr then at
   *least
   *   the <code>addToLocalCache</code> parameter should be true and caching
   *   should be enabled for the region to get values into the region
   *   otherwise an <code>IllegalArgumentException</code> is thrown.
   * @param exceptions Output parameter that provides the map of keys
   *   to any exceptions while obtaining the key. It is ignored if nullptr.
   * @since 8.1
   * @param aCallbackArgument an argument that is passed to the callback
   *functions.
   * It may be nullptr. Must be serializable if this operation is distributed.
   * @throws IllegalArgumentException If the array of keys is empty. Other
   *   invalid case is when the <code>values</code> parameter is nullptr, and
   *   either <code>addToLocalCache</code> is false or caching is disabled
   *   for this region.
   * @throws CacheServerException If an exception is received from the Java
   *   cache server while processing the request.
   * @throws NotConnectedException if it is not connected to the cache because
   *   the client cannot establish usable connections to any of the given
   *servers For pools configured with locators, if no locators are available,
   *the cause of NotConnectedException is set to
   *NoAvailableLocatorsException.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws TimeoutException if operation timed out.
   * @throws UnknownException For other exceptions.
   *
   * @see get
   */
  virtual HashMapOfCacheable getAll(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /**
   * Executes the query on the server based on the predicate.
   * Valid only for a Native Client region.
   *
   * @param predicate The query predicate (just the WHERE clause) or the entire
   * query to execute.
   * @param timeout The time to wait for the query response, optional.
   *
   * @throws IllegalArgumentException If timeout exceeds 2147483647ms.
   * @throws QueryException if some query error occurred at the server.
   * @throws CacheServerException If an exception is received from the Java
   * cache server.
   * @throws NotConnectedException if a server connection error occurs.
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if operation timed out
   * @throws CacheClosedException if the cache has been closed
   *
   * @returns A smart pointer to the SelectResults which can either be a
   * ResultSet or a StructSet.
   */
  virtual std::shared_ptr<SelectResults> query(
      const std::string& predicate,
      std::chrono::milliseconds timeout = DEFAULT_QUERY_RESPONSE_TIMEOUT) = 0;

  /**
   * Executes the query on the server based on the predicate and returns whether
   * any result exists.
   * Valid only for a Native Client region.
   * @param predicate The query predicate (just the WHERE clause) or the entire
   * query to execute.
   * @param timeout The time to wait for the response, optional.
   * @throws IllegalArgumentException If timeout exceeds 2147483647ms.
   * @throws QueryException if some query error occurred at the server.
   * @throws NotConnectedException if a server connection error occurs.
   *         For pools configured with locators, if no locators are available,
   *         the cause of NotConnectedException is set to
   *         NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when the reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if operation timed out
   * @throws CacheClosedException if the cache has been closed
   * @returns true if the result size is non-zero, false otherwise.
   */
  virtual bool existsValue(
      const std::string& predicate,
      std::chrono::milliseconds timeout = DEFAULT_QUERY_RESPONSE_TIMEOUT) = 0;

  /**
   * Executes the query on the server based on the predicate and returns a
   * single result value. Valid only for a Native Client region.
   * @param predicate The query predicate (just the WHERE clause) or the entire
   * query to execute.
   * @param timeout The time to wait for the response, optional.
   * @throws IllegalArgumentException If timeout exceeds 2147483647ms.
   * @throws QueryException if some query error occurred at the server, or more
   * than one result items are available.
   * @throws NotConnectedException if a server connection error occurs.
   *         For pools configured with locators, if no locators are available,
   * the cause
   *         of NotConnectedException is set to NoAvailableLocatorsException.
   * @throws MessageExcepton If the message received from server could not be
   *         handled. This will be the case when an unregistered typeId is
   *         received in the reply or reply is not well formed.
   *         More information can be found in the log.
   * @throws TimeoutException if operation timed out
   * @throws CacheClosedException if the cache has been closed
   * @returns A smart pointer to the single ResultSet or StructSet item, or
   * nullptr of no results are available.
   */
  virtual std::shared_ptr<Serializable> selectValue(
      const std::string& predicate,
      std::chrono::milliseconds timeout = DEFAULT_QUERY_RESPONSE_TIMEOUT) = 0;

  /**
   * Removes all of the entries for the specified keys from this region.
   * The effect of this call is equivalent to that of calling {@link #destroy}
   * on this region once for each key in the specified collection. If an entry
   * does not exist that key is skipped; EntryNotFoundException is not thrown.
   * <p>Updates the {@link CacheStatistics::getLastAccessedTime} and
   * {@link CacheStatistics::getLastModifiedTime} for this region and
   * the entries.
   * @since 8.1
   * @param keys the keys to remove from this region.
   * @param aCallbackArgument an argument that is passed to the callback
   * functions.
   *  It is ignored if nullptr. It must be serializable if this operation is
   * distributed.
   * @throws IllegalArgumentException If the array of keys is empty.
   * @throws CacheServerException If an exception is received from the Java
   *   cache server while processing the request.
   * @throws NotConnectedException if it is not connected to the cache because
   *   the client cannot establish usable connections to any of the given
   * servers For pools configured with locators, if no locators are available,
   * the cause of NotConnectedException is set to
   * NoAvailableLocatorsException.
   * @throws RegionDestroyedException If region destroy is pending.
   * @throws TimeoutException if operation timed out.
   * @throws UnknownException For other exceptions.
   * @see destroy
   */
  virtual void removeAll(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr) = 0;

  /**
   * Get the size of region. For native client regions, this will give the
   * number of entries in the local cache and not on the servers.
   */
  virtual uint32_t size() = 0;

  virtual const std::shared_ptr<Pool>& getPool() const = 0;

  Cache& getCache();

  Region(const Region&) = delete;
  Region& operator=(const Region&) = delete;

 protected:
  explicit Region(CacheImpl* cacheImpl);
  virtual ~Region() noexcept;

  CacheImpl* m_cacheImpl;
};

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

#endif  // GEODE_REGION_H_
