/*
 * 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.
 */
package org.apache.geode.internal.cache;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;

import org.apache.geode.CancelCriterion;
import org.apache.geode.Statistics;
import org.apache.geode.cache.CacheWriter;
import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.EntryNotFoundException;
import org.apache.geode.cache.Operation;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.RegionExistsException;
import org.apache.geode.cache.TimeoutException;
import org.apache.geode.cache.TransactionId;
import org.apache.geode.cache.client.internal.ServerRegionProxy;
import org.apache.geode.cache.query.internal.index.IndexManager;
import org.apache.geode.cache.util.ObjectSizer;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.internal.DistributionManager;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.internal.cache.eviction.EvictionController;
import org.apache.geode.internal.cache.persistence.DiskExceptionHandler;
import org.apache.geode.internal.cache.persistence.DiskRecoveryStore;
import org.apache.geode.internal.cache.tier.sockets.CacheClientNotifier;
import org.apache.geode.internal.cache.tier.sockets.ClientProxyMembershipID;
import org.apache.geode.internal.cache.tier.sockets.VersionedObjectList;
import org.apache.geode.internal.cache.versions.RegionVersionVector;
import org.apache.geode.internal.cache.versions.VersionSource;
import org.apache.geode.internal.cache.versions.VersionTag;
import org.apache.geode.internal.util.concurrent.StoppableCountDownLatch;

/**
 * Interface to be used instead of type-casting to LocalRegion.
 *
 * <p>
 * The following interfaces are implemented by LocalRegion and may need to be extended by
 * InternalRegion to completely allow code to move to using InternalRegion:
 * <ul>
 * <li>RegionAttributes
 * <li>AttributesMutator
 * <li>CacheStatistics
 * <li>DataSerializableFixedID
 * <li>RegionEntryContext
 * <li>Extensible
 * </ul>
 */
@SuppressWarnings("rawtypes")
public interface InternalRegion extends Region, HasCachePerfStats, RegionEntryContext,
    RegionAttributes, HasDiskRegion, RegionMapOwner, DiskExceptionHandler, DiskRecoveryStore {

  int getLocalSize();

  @Override
  CachePerfStats getCachePerfStats();

  @Override
  DiskRegion getDiskRegion();

  RegionEntry getRegionEntry(Object key);

  RegionVersionVector getVersionVector();

  long cacheTimeMillis();

  Object getValueInVM(Object key) throws EntryNotFoundException;

  Object getValueOnDisk(Object key) throws EntryNotFoundException;

  void dispatchListenerEvent(EnumListenerEvent op, InternalCacheEvent event);

  boolean isUsedForPartitionedRegionAdmin();

  ImageState getImageState();

  VersionSource getVersionMember();

  long updateStatsForPut(RegionEntry entry, long lastModified, boolean lruRecentUse);

  FilterProfile getFilterProfile();

  ServerRegionProxy getServerProxy();

  void unscheduleTombstone(RegionEntry entry);

  void scheduleTombstone(RegionEntry entry, VersionTag destroyedVersion);

  void scheduleTombstone(RegionEntry entry, VersionTag destroyedVersion, boolean reschedule);

  boolean isEntryExpiryPossible();

  void addExpiryTaskIfAbsent(RegionEntry entry);

  /**
   * Used by unit tests to get access to the EntryExpiryTask of the given key. Returns null if the
   * entry exists but does not have an expiry task.
   *
   * @throws EntryNotFoundException if no entry exists key.
   */
  EntryExpiryTask getEntryExpiryTask(Object key);

  DistributionManager getDistributionManager();

  void generateAndSetVersionTag(InternalCacheEvent event, RegionEntry entry);

  boolean cacheWriteBeforeDestroy(EntryEventImpl event, Object expectedOldValue)
      throws CacheWriterException, EntryNotFoundException, TimeoutException;

  void recordEvent(InternalCacheEvent event);

  boolean isProxy();

  Lock getClientMetaDataLock();

  IndexManager getIndexManager();

  boolean isThisRegionBeingClosedOrDestroyed();

  CancelCriterion getCancelCriterion();

  boolean isIndexCreationThread();

  int updateSizeOnEvict(Object key, int oldSize);

  RegionEntry basicGetEntry(Object key);

  void invokePutCallbacks(final EnumListenerEvent eventType, final EntryEventImpl event,
      final boolean callDispatchListenerEvent, boolean notifyGateways);

  void invokeDestroyCallbacks(final EnumListenerEvent eventType, final EntryEventImpl event,
      final boolean callDispatchListenerEvent, boolean notifyGateways);

  void invokeInvalidateCallbacks(final EnumListenerEvent eventType, final EntryEventImpl event,
      final boolean callDispatchListenerEvent);

  long getTotalEvictions();

  Region createSubregion(String subregionName, RegionAttributes attrs,
      InternalRegionArguments internalRegionArgs)
      throws RegionExistsException, TimeoutException, IOException, ClassNotFoundException;

  void addCacheServiceProfile(CacheServiceProfile profile);

  void setEvictionMaximum(int maximum);

  /**
   * Returns null if the region is not configured for eviction otherwise returns the Statistics used
   * to measure eviction activity.
   */
  Statistics getEvictionStatistics();

  long getEvictionCounter();

  RegionMap getRegionMap();

  InternalDistributedSystem getSystem();

  int getRegionSize();

  void basicDestroyBeforeRemoval(RegionEntry entry, EntryEventImpl event);

  void basicDestroyPart2(RegionEntry re, EntryEventImpl event, boolean inTokenMode,
      boolean conflictWithClear, boolean duringRI, boolean invokeCallbacks);

  void notifyTimestampsToGateways(EntryEventImpl event);

  boolean bridgeWriteBeforeDestroy(EntryEventImpl event, Object expectedOldValue)
      throws CacheWriterException, EntryNotFoundException, TimeoutException;

  void checkEntryNotFound(Object entryKey);

  void rescheduleTombstone(RegionEntry entry, VersionTag version);

  /**
   * Throws CacheClosedException or RegionDestroyedException
   */
  void checkReadiness();

  void basicDestroyPart3(RegionEntry re, EntryEventImpl event, boolean inTokenMode,
      boolean duringRI, boolean invokeCallbacks, Object expectedOldValue);

  void cancelExpiryTask(RegionEntry regionEntry);

  boolean hasServerProxy();

  int calculateRegionEntryValueSize(RegionEntry re);

  void updateSizeOnRemove(Object key, int oldSize);

  boolean isEntryEvictionPossible();

  KeyInfo getKeyInfo(Object key);

  void waitOnInitialization();

  void waitOnInitialization(StoppableCountDownLatch latch);

  Set<InternalRegion> basicSubregions(boolean recursive);

  boolean isSecret();

  boolean isUsedForMetaRegion();

  boolean isInternalRegion();

  void handleCacheClose(Operation op);

  /**
   * Execute any validation required prior to initializing the region.
   * This method should throw an exception whenever an invalid configuration is detected.
   */
  default void preInitialize() {
    // Do nothing by default.
  }

  void initialize(InputStream snapshotInputStream, InternalDistributedMember imageTarget,
      InternalRegionArguments internalRegionArgs)
      throws TimeoutException, IOException, ClassNotFoundException;

  void cleanupFailedInitialization();

  void postCreateRegion();

  Region getSubregion(String string, boolean b);

  boolean checkForInitialization();

  boolean isUsedForPartitionedRegionBucket();

  Set<String> getAllGatewaySenderIds();

  void senderCreated();

  boolean isInitialized();

  void cleanupForClient(CacheClientNotifier ccn, ClientProxyMembershipID client);

  InternalDistributedMember getMyId();

  /**
   * The default Region implementation will generate EvenTID in the EntryEvent object. This method
   * is overridden in special Region objects like HARegion or
   * SingleWriteSingleReadRegionQueue.SingleReadWriteMetaRegion
   * to return false as the event propagation from those regions do not need EventID objects. This
   * method is made abstract to directly use it in clear operations. (clear and localclear)
   *
   * @return boolean indicating whether to generate eventID or not
   */
  boolean generateEventID();

  boolean containsTombstone(Object key);

  CacheWriter basicGetWriter();

  void basicPutPart3(EntryEventImpl event, RegionEntry regionEntry, boolean isInitialized,
      long lastModifiedTime, boolean invokeListeners, boolean ifNew, boolean ifOld,
      Object expectedOldValue, boolean requireOldValue);

  long basicPutPart2(EntryEventImpl event, RegionEntry re, boolean isInitialized,
      long lastModifiedTime, boolean clearOccured);

  int calculateValueSize(Object v);

  void cacheWriteBeforePut(EntryEventImpl event, Set netWriteRecipients, CacheWriter cacheWriter,
      boolean requireOldValue, Object expectedOldValue);

  void updateSizeOnPut(Object key, int oldSize, int newBucketSize);

  void updateSizeOnCreate(Object key, int newBucketSize);

  boolean isCopyOnRead();

  Object getValueInVMOrDiskWithoutFaultIn(Object key);

  boolean isRegionInvalid();

  void setRegionInvalid(boolean b);

  ObjectSizer getObjectSizer();

  boolean hasSeenEvent(EntryEventImpl entryEvent);

  TXId getTXId();

  KeyInfo getKeyInfo(Object key, Object newVal, Object callbackArgument);

  void invokeTXCallbacks(EnumListenerEvent afterDestroy, EntryEventImpl ee, boolean b);

  void invokeTXCallbacks(EnumListenerEvent afterDestroy, EntryEventImpl ee, boolean b,
      boolean isLastEventInTransaction);

  LocalRegion getPartitionedRegion();

  void checkIfAboveThreshold(EntryEventImpl event);

  LocalRegion getDataRegionForRead(KeyInfo keyInfo);

  InternalRegion getDataRegionForWrite(KeyInfo keyInfo);

  TXEntryState createReadEntry(TXRegionState txr, KeyInfo keyInfo, boolean createIfAbsent);

  void syncBulkOp(Runnable task, EventID eventId);

  Object getDataView();

  boolean basicPut(EntryEventImpl ev, boolean b, boolean b1, Object o, boolean b2);

  void basicDestroy(EntryEventImpl ev, boolean b, Object o);

  DistributedMember getOwnerForKey(KeyInfo key);

  boolean isMetaRegionWithTransactions();

  void setInUseByTransaction(boolean b);

  boolean txLRUStart();

  void txLRUEnd();

  void txDecRefCount(RegionEntry refCountEntry);

  Object getDisplayName();

  Object basicGetEntryUserAttribute(Object key);

  boolean requiresReliabilityCheck();

  boolean lockGII();

  void unlockGII();

  boolean hasSeenEvent(EventID eventID);

  void txApplyDestroy(Object key, TransactionId rmtOrigin, TXRmtEvent event,
      boolean needTokensForGII, Operation op, EventID eventId, Object aCallbackArgument,
      List<EntryEventImpl> pendingCallbacks, FilterRoutingInfo filterRoutingInfo,
      ClientProxyMembershipID bridgeContext, boolean isOriginRemote, TXEntryState txEntryState,
      VersionTag versionTag, long tailKey);


  void txApplyInvalidate(Object key, Object newValue, boolean didDestroy,
      TransactionId transactionId, TXRmtEvent event, boolean localOp, EventID eventId,
      Object aCallbackArgument, List<EntryEventImpl> pendingCallbacks,
      FilterRoutingInfo filterRoutingInfo, ClientProxyMembershipID bridgeContext,
      TXEntryState txEntryState, VersionTag versionTag, long tailKey);

  void txApplyPut(Operation putOp, Object key, Object newValue, boolean didDestroy,
      TransactionId transactionId, TXRmtEvent event, EventID eventId, Object aCallbackArgument,
      List<EntryEventImpl> pendingCallbacks, FilterRoutingInfo filterRoutingInfo,
      ClientProxyMembershipID bridgeContext, TXEntryState txEntryState, VersionTag versionTag,
      long tailKey);

  void txApplyPutPart2(RegionEntry regionEntry, Object key, long lastModified, boolean isCreate,
      boolean didDestroy, boolean clearConflict);

  void txApplyPutHandleDidDestroy(Object key);

  void handleReliableDistribution(Set successfulRecipients);

  StoppableCountDownLatch getInitializationLatchBeforeGetInitialImage();

  StoppableCountDownLatch getInitializationLatchAfterGetInitialImage();

  boolean mapDestroy(EntryEventImpl event, boolean cacheWrite, boolean b, Object expectedOldValue);

  boolean virtualPut(EntryEventImpl event, boolean ifNew, boolean ifOld, Object expectedOldValue,
      boolean requireOldValue, long lastModified, boolean overwriteDestroyed);

  boolean virtualPut(EntryEventImpl event, boolean ifNew, boolean ifOld, Object expectedOldValue,
      boolean requireOldValue, long lastModified, boolean overwriteDestroyed,
      boolean invokeCallbacks,
      boolean throwsConcurrentModification);

  long postPutAllSend(DistributedPutAllOperation putallOp, VersionedObjectList successfulPuts);

  void postPutAllFireEvents(DistributedPutAllOperation putallOp,
      VersionedObjectList successfulPuts);

  long postRemoveAllSend(DistributedRemoveAllOperation op, VersionedObjectList successfulOps);

  void postRemoveAllFireEvents(DistributedRemoveAllOperation op, VersionedObjectList successfulOps);

  VersionTag findVersionTagForEvent(EventID eventId);

  Object getIMSync();

  void setIndexManager(IndexManager idxMgr);

  RegionTTLExpiryTask getRegionTTLExpiryTask();

  RegionIdleExpiryTask getRegionIdleExpiryTask();

  boolean isAllEvents();

  boolean shouldDispatchListenerEvent();

  boolean shouldNotifyBridgeClients();

  default Set adviseNetWrite() {
    return null;
  }

  EvictionController getEvictionController();

  default void handleWANEvent(EntryEventImpl event) {
    // do nothing;
  }

  MemoryThresholdInfo getAtomicThresholdInfo();

  InternalCache getInternalCache();

  default boolean lockWhenRegionIsInitializing() {
    return false;
  }

  default void unlockWhenRegionIsInitializing() {
    // do nothing
  }

  Map<Object, Object> getEntryUserAttributes();

  int getTombstoneCount();

  Region.Entry getEntry(Object key, boolean allowTombstones);

  Set<String> getVisibleAsyncEventQueueIds();

  CachePerfStats getRegionPerfStats();

  VersionedObjectList basicRemoveAll(Collection<Object> keys,
      DistributedRemoveAllOperation removeAllOp, List<VersionTag> retryVersions);

  VersionTag getVersionTag(Object key);

  /**
   * This method determines whether this region should synchronize with peer replicated regions when
   * the given member has crashed.
   *
   * @param id the crashed member
   * @return true if synchronization should be attempted
   */
  boolean shouldSyncForCrashedMember(InternalDistributedMember id);

  boolean isRegionCreateNotified();

  void setRegionCreateNotified(boolean notified);
}
