/*
 * 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_LOCALREGION_H_
#define GEODE_LOCALREGION_H_

#include <string>
#include <unordered_map>

#include <geode/AttributesMutator.hpp>
#include <geode/Cache.hpp>
#include <geode/CacheListener.hpp>
#include <geode/CacheLoader.hpp>
#include <geode/CacheStatistics.hpp>
#include <geode/CacheWriter.hpp>
#include <geode/CacheableKey.hpp>
#include <geode/EntryEvent.hpp>
#include <geode/ExceptionTypes.hpp>
#include <geode/PersistenceManager.hpp>
#include <geode/RegionAttributesFactory.hpp>
#include <geode/RegionEntry.hpp>
#include <geode/RegionEvent.hpp>
#include <geode/Serializable.hpp>
#include <geode/internal/geode_globals.hpp>

#include "CacheableToken.hpp"
#include "EntriesMapFactory.hpp"
#include "EventType.hpp"
#include "ExpMapEntry.hpp"
#include "RegionInternal.hpp"
#include "RegionStats.hpp"
#include "SerializationRegistry.hpp"
#include "TSSTXStateWrapper.hpp"
#include "TombstoneList.hpp"
#include "util/synchronized_map.hpp"

namespace apache {
namespace geode {
namespace client {

#ifndef CHECK_DESTROY_PENDING
#define CHECK_DESTROY_PENDING(lock, function)           \
  lock checkGuard(m_rwLock, m_destroyPending);          \
  if (m_destroyPending) {                               \
    std::string err_msg = #function;                    \
    err_msg += ": region " + m_fullPath + " destroyed"; \
    throw RegionDestroyedException(err_msg.c_str());    \
  }
#endif

#ifndef CHECK_DESTROY_PENDING_NOTHROW
#define CHECK_DESTROY_PENDING_NOTHROW(lock)     \
  lock checkGuard(m_rwLock, m_destroyPending);  \
  if (m_destroyPending) {                       \
    return GF_CACHE_REGION_DESTROYED_EXCEPTION; \
  }
#endif

class PutActions;
class PutActionsTx;
class CreateActions;
class DestroyActions;
class RemoveActions;
class InvalidateActions;

typedef std::unordered_map<std::shared_ptr<CacheableKey>,
                           std::pair<std::shared_ptr<Cacheable>, int>>
    MapOfOldValue;

/**
 * @class LocalRegion LocalRegion.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.
 *
 * 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.
 */

class APACHE_GEODE_EXPORT LocalRegion : public RegionInternal {
  /**
   * @brief Public Methods for Region
   */
 public:
  LocalRegion(const std::string& name, CacheImpl* cache,
              const std::shared_ptr<RegionInternal>& rPtr,
              RegionAttributes attributes,
              const std::shared_ptr<CacheStatistics>& stats,
              bool enableTimeStatistics = true);

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

  ~LocalRegion() noexcept override;

  const std::string& getName() const override;
  const std::string& getFullPath() const override;
  std::shared_ptr<Region> getParentRegion() const override;
  const RegionAttributes& getAttributes() const override {
    return m_regionAttributes;
  }
  std::shared_ptr<AttributesMutator> getAttributesMutator() const override {
    return std::make_shared<AttributesMutator>(
        std::const_pointer_cast<LocalRegion>(
            std::static_pointer_cast<const LocalRegion>(shared_from_this())));
  }
  void updateAccessAndModifiedTime(bool modified) override;
  std::shared_ptr<CacheStatistics> getStatistics() const override;
  void clear(const std::shared_ptr<Serializable>& aCallbackArgument =
                 nullptr) override;
  void localClear(const std::shared_ptr<Serializable>& aCallbackArgument =
                      nullptr) override;
  GfErrType localClearNoThrow(
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr,
      const CacheEventFlags eventFlags = CacheEventFlags::NORMAL);
  void invalidateRegion(const std::shared_ptr<Serializable>& aCallbackArgument =
                            nullptr) override;
  void localInvalidateRegion(const std::shared_ptr<Serializable>&
                                 aCallbackArgument = nullptr) override;
  void destroyRegion(const std::shared_ptr<Serializable>& aCallbackArgument =
                         nullptr) override;
  void localDestroyRegion(const std::shared_ptr<Serializable>&
                              aCallbackArgument = nullptr) override;
  std::shared_ptr<Region> getSubregion(const std::string& path) override;
  std::shared_ptr<Region> createSubregion(
      const std::string& subregionName,
      RegionAttributes regionAttributes) override;
  std::vector<std::shared_ptr<Region>> subregions(
      const bool recursive) override;
  std::shared_ptr<RegionEntry> getEntry(
      const std::shared_ptr<CacheableKey>& key) override;
  void getEntry(const std::shared_ptr<CacheableKey>& key,
                std::shared_ptr<Cacheable>& valuePtr);
  std::shared_ptr<Cacheable> get(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument) override;
  void put(const std::shared_ptr<CacheableKey>& key,
           const std::shared_ptr<Cacheable>& value,
           const std::shared_ptr<Serializable>& aCallbackArgument =
               nullptr) override;
  void localPut(const std::shared_ptr<CacheableKey>& key,
                const std::shared_ptr<Cacheable>& value,
                const std::shared_ptr<Serializable>& aCallbackArgument =
                    nullptr) override;
  void create(const std::shared_ptr<CacheableKey>& key,
              const std::shared_ptr<Cacheable>& value,
              const std::shared_ptr<Serializable>& aCallbackArgument =
                  nullptr) override;
  void localCreate(const std::shared_ptr<CacheableKey>& key,
                   const std::shared_ptr<Cacheable>& value,
                   const std::shared_ptr<Serializable>& aCallbackArgument =
                       nullptr) override;
  void invalidate(const std::shared_ptr<CacheableKey>& key,
                  const std::shared_ptr<Serializable>& aCallbackArgument =
                      nullptr) override;
  void localInvalidate(const std::shared_ptr<CacheableKey>& key,
                       const std::shared_ptr<Serializable>& aCallbackArgument =
                           nullptr) override;
  void destroy(const std::shared_ptr<CacheableKey>& key,
               const std::shared_ptr<Serializable>& aCallbackArgument =
                   nullptr) override;
  void localDestroy(const std::shared_ptr<CacheableKey>& key,
                    const std::shared_ptr<Serializable>& aCallbackArgument =
                        nullptr) override;
  bool remove(const std::shared_ptr<CacheableKey>& key,
              const std::shared_ptr<Cacheable>& value,
              const std::shared_ptr<Serializable>& aCallbackArgument =
                  nullptr) override;
  bool removeEx(const std::shared_ptr<CacheableKey>& key,
                const std::shared_ptr<Serializable>& aCallbackArgument =
                    nullptr) override;
  bool localRemove(const std::shared_ptr<CacheableKey>& key,
                   const std::shared_ptr<Cacheable>& value,
                   const std::shared_ptr<Serializable>& aCallbackArgument =
                       nullptr) override;
  bool localRemoveEx(const std::shared_ptr<CacheableKey>& key,
                     const std::shared_ptr<Serializable>& aCallbackArgument =
                         nullptr) override;
  std::vector<std::shared_ptr<CacheableKey>> keys() override;
  std::vector<std::shared_ptr<CacheableKey>> serverKeys() override;
  std::vector<std::shared_ptr<Cacheable>> values() override;
  std::vector<std::shared_ptr<RegionEntry>> entries(bool recursive) override;

  HashMapOfCacheable getAll(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      const std::shared_ptr<Serializable>& aCallbackArgument =
          nullptr) override;

  HashMapOfCacheable getAll_internal(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      bool addToLocalCache) override;

  void putAll(const HashMapOfCacheable& map,
              std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT,
              const std::shared_ptr<Serializable>& aCallbackArgument =
                  nullptr) override;
  void removeAll(const std::vector<std::shared_ptr<CacheableKey>>& keys,
                 const std::shared_ptr<Serializable>& aCallbackArgument =
                     nullptr) override;
  uint32_t size() override;
  virtual uint32_t size_remote();
  RegionService& getRegionService() const override;
  virtual bool containsValueForKey_remote(
      const std::shared_ptr<CacheableKey>& keyPtr) const;
  bool containsValueForKey(
      const std::shared_ptr<CacheableKey>& keyPtr) const override;
  bool containsKey(const std::shared_ptr<CacheableKey>& keyPtr) const override;
  virtual bool containsKeyOnServer(
      const std::shared_ptr<CacheableKey>& keyPtr) const override;
  std::vector<std::shared_ptr<CacheableKey>> getInterestList() const override;
  std::vector<std::shared_ptr<CacheableString>> getInterestListRegex()
      const override;

  /** @brief Public Methods from RegionInternal
   *  There are all virtual methods
   */
  std::shared_ptr<PersistenceManager> getPersistenceManager() override {
    return m_persistenceManager;
  }
  void setPersistenceManager(
      std::shared_ptr<PersistenceManager>& pmPtr) override;

  GfErrType getNoThrow(
      const std::shared_ptr<CacheableKey>& key,
      std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument) override;
  GfErrType getAllNoThrow(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      const std::shared_ptr<HashMapOfCacheable>& values,
      const std::shared_ptr<HashMapOfException>& exceptions,
      const bool addToLocalCache,
      const std::shared_ptr<Serializable>& aCallbackArgument =
          nullptr) override;
  GfErrType putNoThrow(const std::shared_ptr<CacheableKey>& key,
                       const std::shared_ptr<Cacheable>& value,
                       const std::shared_ptr<Serializable>& aCallbackArgument,
                       std::shared_ptr<Cacheable>& oldValue, int updateCount,
                       const CacheEventFlags eventFlags,
                       std::shared_ptr<VersionTag> versionTag,
                       DataInput* delta = nullptr,
                       std::shared_ptr<EventId> eventId = nullptr) override;
  GfErrType putNoThrowTX(const std::shared_ptr<CacheableKey>& key,
                         const std::shared_ptr<Cacheable>& value,
                         const std::shared_ptr<Serializable>& aCallbackArgument,
                         std::shared_ptr<Cacheable>& oldValue, int updateCount,
                         const CacheEventFlags eventFlags,
                         std::shared_ptr<VersionTag> versionTag,
                         DataInput* delta = nullptr,
                         std::shared_ptr<EventId> eventId = nullptr);
  GfErrType createNoThrow(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument, int updateCount,
      const CacheEventFlags eventFlags,
      std::shared_ptr<VersionTag> versionTag) override;
  GfErrType destroyNoThrow(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument, int updateCount,
      const CacheEventFlags eventFlags,
      std::shared_ptr<VersionTag> versionTag) override;
  virtual GfErrType destroyNoThrowTX(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument, int updateCount,
      const CacheEventFlags eventFlags, std::shared_ptr<VersionTag> versionTag);
  GfErrType removeNoThrow(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument, int updateCount,
      const CacheEventFlags eventFlags,
      std::shared_ptr<VersionTag> versionTag) override;
  virtual GfErrType removeNoThrowEx(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Serializable>& aCallbackArgument, int updateCount,
      const CacheEventFlags eventFlags, std::shared_ptr<VersionTag> versionTag);
  virtual GfErrType putAllNoThrow(
      const HashMapOfCacheable& map,
      std::chrono::milliseconds timeout = DEFAULT_RESPONSE_TIMEOUT,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr);
  virtual GfErrType removeAllNoThrow(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      const std::shared_ptr<Serializable>& aCallbackArgument = nullptr);
  GfErrType invalidateNoThrow(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Serializable>& aCallbackArgument, int updateCount,
      const CacheEventFlags eventFlags,
      std::shared_ptr<VersionTag> versionTag) override;
  virtual GfErrType invalidateNoThrowTX(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Serializable>& aCallbackArgument, int updateCount,
      const CacheEventFlags eventFlags, std::shared_ptr<VersionTag> versionTag);
  GfErrType invalidateRegionNoThrow(
      const std::shared_ptr<Serializable>& aCallbackArgument,
      const CacheEventFlags eventFlags) override;
  GfErrType destroyRegionNoThrow(
      const std::shared_ptr<Serializable>& aCallbackArgument,
      bool removeFromParent, const CacheEventFlags eventFlags) override;
  void tombstoneOperationNoThrow(
      const std::shared_ptr<CacheableHashMap>& tombstoneVersions,
      const std::shared_ptr<CacheableHashSet>& tombstoneKeys);

  //  moved putLocal to public since this is used by a few other
  // classes like CacheableObjectPartList now
  /** put an entry in local cache without invoking any callbacks */
  GfErrType putLocal(const std::string& name, bool isCreate,
                     const std::shared_ptr<CacheableKey>& keyPtr,
                     const std::shared_ptr<Cacheable>& valuePtr,
                     std::shared_ptr<Cacheable>& oldValue, bool cachingEnabled,
                     int updateCount, int destroyTracker,
                     std::shared_ptr<VersionTag> versionTag,
                     DataInput* delta = nullptr,
                     std::shared_ptr<EventId> eventId = nullptr);
  GfErrType invalidateLocal(const std::string& name,
                            const std::shared_ptr<CacheableKey>& keyPtr,
                            const std::shared_ptr<Cacheable>& value,
                            const CacheEventFlags eventFlags,
                            std::shared_ptr<VersionTag> versionTag);

  void setRegionExpiryTask() override;
  void acquireReadLock() override { m_rwLock.acquire_read(); }
  void releaseReadLock() override { m_rwLock.release(); }

  // behaviors for attributes mutator
  uint32_t adjustLruEntriesLimit(uint32_t limit) override;
  ExpirationAction adjustRegionExpiryAction(ExpirationAction action) override;
  ExpirationAction adjustEntryExpiryAction(ExpirationAction action) override;
  std::chrono::seconds adjustRegionExpiryDuration(
      const std::chrono::seconds& duration) override;
  std::chrono::seconds adjustEntryExpiryDuration(
      const std::chrono::seconds& duration) override;

  // other public methods
  RegionStats* getRegionStats() override { return m_regionStats; }

  bool cacheEnabled() override {
    return m_regionAttributes.getCachingEnabled();
  }

  inline bool cachelessWithListener() {
    return !m_regionAttributes.getCachingEnabled() && (m_listener != nullptr);
  }

  bool isDestroyed() const override { return m_destroyPending; }
  /* above public methods are inherited from RegionInternal */

  void adjustCacheListener(
      const std::shared_ptr<CacheListener>& aListener) override;

  void adjustCacheListener(const std::string& libpath,
                           const std::string& factoryFuncName) override;
  void adjustCacheLoader(const std::shared_ptr<CacheLoader>& aLoader) override;

  void adjustCacheLoader(const std::string& libpath,
                         const std::string& factoryFuncName) override;
  void adjustCacheWriter(const std::shared_ptr<CacheWriter>& aWriter) override;

  void adjustCacheWriter(const std::string& libpath,
                         const std::string& factoryFuncName) override;
  CacheImpl* getCacheImpl() const override;

  void evict(int32_t percentage) override;

  virtual void acquireGlobals(bool isFailover);

  virtual void releaseGlobals(bool isFailover);

  virtual bool getProcessedMarker() { return true; }

  EntriesMap* getEntryMap() { return m_entries; }

  std::shared_ptr<TombstoneList> getTombstoneList() override;

 protected:
  /* virtual protected methods */
  virtual void release(bool invokeCallbacks = true);
  virtual GfErrType getNoThrow_remote(
      const std::shared_ptr<CacheableKey>& keyPtr,
      std::shared_ptr<Cacheable>& valPtr,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<VersionTag>& versionTag);
  virtual GfErrType putNoThrow_remote(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Cacheable>& cvalue,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<VersionTag>& versionTag, bool checkDelta = true);
  virtual GfErrType putAllNoThrow_remote(
      const HashMapOfCacheable& map,
      std::shared_ptr<VersionedCacheableObjectPartList>& versionedObjPartList,
      std::chrono::milliseconds timeout,
      const std::shared_ptr<Serializable>& aCallbackArgument);
  virtual GfErrType removeAllNoThrow_remote(
      const std::vector<std::shared_ptr<CacheableKey>>& keys,
      std::shared_ptr<VersionedCacheableObjectPartList>& versionedObjPartList,
      const std::shared_ptr<Serializable>& aCallbackArgument);
  virtual GfErrType createNoThrow_remote(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Cacheable>& cvalue,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<VersionTag>& versionTag);
  virtual GfErrType destroyNoThrow_remote(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<VersionTag>& versionTag);
  virtual GfErrType removeNoThrow_remote(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Cacheable>& cvalue,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<VersionTag>& versionTag);
  virtual GfErrType removeNoThrowEX_remote(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<VersionTag>& versionTag);
  virtual GfErrType invalidateNoThrow_remote(
      const std::shared_ptr<CacheableKey>& keyPtr,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<VersionTag>& versionTag);
  virtual GfErrType getAllNoThrow_remote(
      const std::vector<std::shared_ptr<CacheableKey>>* keys,
      const std::shared_ptr<HashMapOfCacheable>& values,
      const std::shared_ptr<HashMapOfException>& exceptions,
      const std::shared_ptr<std::vector<std::shared_ptr<CacheableKey>>>&
          resultKeys,
      bool addToLocalCache,
      const std::shared_ptr<Serializable>& aCallbackArgument);
  virtual GfErrType invalidateRegionNoThrow_remote(
      const std::shared_ptr<Serializable>& aCallbackArgument);
  virtual GfErrType destroyRegionNoThrow_remote(
      const std::shared_ptr<Serializable>& aCallbackArgument);
  virtual GfErrType unregisterKeysBeforeDestroyRegion();
  const std::shared_ptr<Pool>& getPool() const override {
    return m_attachedPool;
  }

  void setPool(const std::shared_ptr<Pool>& p) { m_attachedPool = p; }

  TXState* getTXState() const { return TSSTXStateWrapper::get().getTXState(); }

  std::shared_ptr<Cacheable> handleReplay(
      GfErrType& err, std::shared_ptr<Cacheable> value) const;

  bool isLocalOp(const CacheEventFlags* eventFlags = nullptr) {
    return typeid(*this) == typeid(LocalRegion) ||
           (eventFlags && eventFlags->isLocal());
  }

  // template method for put and create
  template <typename TAction>
  GfErrType updateNoThrow(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<Cacheable>& oldValue, int updateCount,
      const CacheEventFlags eventFlags, std::shared_ptr<VersionTag> versionTag,
      DataInput* delta = nullptr, std::shared_ptr<EventId> eventId = nullptr);

  template <typename TAction>
  GfErrType updateNoThrowTX(
      const std::shared_ptr<CacheableKey>& key,
      const std::shared_ptr<Cacheable>& value,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      std::shared_ptr<Cacheable>& oldValue, int updateCount,
      const CacheEventFlags eventFlags, std::shared_ptr<VersionTag> versionTag,
      DataInput* delta = nullptr, std::shared_ptr<EventId> eventId = nullptr);

  int64_t startStatOpTime();
  void updateStatOpTime(Statistics* m_regionStats, int32_t statId,
                        int64_t start);

  /* protected attributes */
  std::string m_name;
  std::shared_ptr<Region> m_parentRegion;
  synchronized_map<std::unordered_map<std::string, std::shared_ptr<Region>>,
                   std::recursive_mutex>
      m_subRegions;
  std::string m_fullPath;
  volatile bool m_destroyPending;
  std::shared_ptr<CacheListener> m_listener;
  std::shared_ptr<CacheWriter> m_writer;
  std::shared_ptr<CacheLoader> m_loader;
  volatile bool m_released;
  EntriesMap* m_entries;  // map containing cache entries...
  RegionStats* m_regionStats;
  std::shared_ptr<CacheStatistics> m_cacheStatistics;
  bool m_transactionEnabled;
  std::shared_ptr<TombstoneList> m_tombstoneList;
  bool m_isPRSingleHopEnabled;
  std::shared_ptr<Pool> m_attachedPool;
  bool m_enableTimeStatistics;

  mutable ACE_RW_Thread_Mutex m_rwLock;
  std::vector<std::shared_ptr<CacheableKey>> keys_internal();
  bool containsKey_internal(const std::shared_ptr<CacheableKey>& keyPtr) const;
  void removeRegion(const std::string& name);

  bool invokeCacheWriterForEntryEvent(
      const std::shared_ptr<CacheableKey>& key,
      std::shared_ptr<Cacheable>& oldValue,
      const std::shared_ptr<Cacheable>& newValue,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      CacheEventFlags eventFlags, EntryEventType type);
  bool invokeCacheWriterForRegionEvent(
      const std::shared_ptr<Serializable>& aCallbackArgument,
      CacheEventFlags eventFlags, RegionEventType type);
  GfErrType invokeCacheListenerForEntryEvent(
      const std::shared_ptr<CacheableKey>& key,
      std::shared_ptr<Cacheable>& oldValue,
      const std::shared_ptr<Cacheable>& newValue,
      const std::shared_ptr<Serializable>& aCallbackArgument,
      CacheEventFlags eventFlags, EntryEventType type, bool isLocal = false);
  GfErrType invokeCacheListenerForRegionEvent(
      const std::shared_ptr<Serializable>& aCallbackArgument,
      CacheEventFlags eventFlags, RegionEventType type);
  // functions related to expirations.
  void updateAccessAndModifiedTimeForEntry(std::shared_ptr<MapEntryImpl>& ptr,
                                           bool modified) override;
  void registerEntryExpiryTask(std::shared_ptr<MapEntryImpl>& entry);
  std::vector<std::shared_ptr<Region>> subregions_internal(
      const bool recursive);
  void entries_internal(std::vector<std::shared_ptr<RegionEntry>>& me,
                        const bool recursive);

  std::shared_ptr<PersistenceManager> m_persistenceManager;

  bool isStatisticsEnabled();
  bool useModifiedTimeForRegionExpiry();
  bool useModifiedTimeForEntryExpiry();
  bool isEntryIdletimeEnabled();
  ExpirationAction getEntryExpirationAction() const;
  ExpirationAction getRegionExpiryAction() const;
  std::chrono::seconds getRegionExpiryDuration() const;
  std::chrono::seconds getEntryExpiryDuration() const;
  void invokeAfterAllEndPointDisconnected();

  virtual GfErrType getNoThrow_FullObject(
      std::shared_ptr<EventId> eventId, std::shared_ptr<Cacheable>& fullObject,
      std::shared_ptr<VersionTag>& versionTag);

 private:
  std::shared_ptr<Region> findSubRegion(const std::string& name);
  GfErrType invalidateRegionNoThrowOnSubRegions(
      const std::shared_ptr<Serializable>& aCallbackArgument,
      const CacheEventFlags eventFlags);

  // these classes encapsulate actions specific to update operations
  // used by the template <code>updateNoThrow</code> class
  friend class PutActions;
  friend class PutActionsTx;
  friend class CreateActions;
  friend class DestroyActions;
  friend class RemoveActions;
  friend class InvalidateActions;
};

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

#endif  // GEODE_LOCALREGION_H_
