/*
 * 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 static org.apache.geode.internal.offheap.annotations.OffHeapIdentifier.ABSTRACT_REGION_ENTRY_FILL_IN_VALUE;
import static org.apache.geode.internal.offheap.annotations.OffHeapIdentifier.ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE;

import org.apache.geode.cache.CacheWriterException;
import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.EntryNotFoundException;
import org.apache.geode.cache.TimeoutException;
import org.apache.geode.distributed.internal.DistributionManager;
import org.apache.geode.internal.InternalStatisticsDisabledException;
import org.apache.geode.internal.cache.InitialImageOperation.Entry;
import org.apache.geode.internal.cache.eviction.EvictionList;
import org.apache.geode.internal.cache.versions.VersionSource;
import org.apache.geode.internal.cache.versions.VersionStamp;
import org.apache.geode.internal.cache.versions.VersionTag;
import org.apache.geode.internal.offheap.StoredObject;
import org.apache.geode.internal.offheap.annotations.Released;
import org.apache.geode.internal.offheap.annotations.Retained;
import org.apache.geode.internal.offheap.annotations.Unretained;
import org.apache.geode.internal.serialization.ByteArrayDataInput;
import org.apache.geode.internal.serialization.Version;

/**
 * Internal interface for a region entry. Note that a region is implemented with a ConcurrentHashMap
 * which has its own entry class. The "value" field of each of these entries will implement this
 * interface.
 *
 * <p>
 * Our RegionEntry does not need to keep a reference to the key. It is being referenced by the
 * Map.Entry whose value field references this RegionEntry.
 *
 * @since GemFire 3.5.1
 */
public interface RegionEntry {

  /**
   * returns the time of last modification. Prior to v7.0 this only reflected creation time of an
   * entry or the time it was last modified with an Update. In 7.0 and later releases it also
   * reflects invalidate and destroy.
   */
  long getLastModified();

  /**
   * Returns true if getLastAccessed, getHitCount, and getMissCount can be called without throwing
   * InternalStatisticsDisabledException. Otherwise returns false.
   *
   * @since GemFire 6.0
   */
  boolean hasStats();

  long getLastAccessed() throws InternalStatisticsDisabledException;

  /**
   * Sets the entry's last accessed time if it has one.
   */
  default void setLastAccessed(long lastAccessed) {
    // do nothing by default
  }

  long getHitCount() throws InternalStatisticsDisabledException;

  long getMissCount() throws InternalStatisticsDisabledException;

  void updateStatsForPut(long lastModifiedTime, long lastAccessedTime);

  /**
   * @return the version information for this entry
   */
  VersionStamp getVersionStamp();

  /**
   * @param member the member performing the change, or null if it's this member
   * @param withDelta whether delta version information should be included
   * @param region the owner of the region entry
   * @param event the event causing this change
   * @return a new version tag for this entry (null if versions not supported)
   */
  VersionTag generateVersionTag(VersionSource member, boolean withDelta, InternalRegion region,
      EntryEventImpl event);

  /**
   * Dispatch listener events for the given entry event. If the event is from another member and
   * there are already pending events, this will merely queue the event for later dispatch by one of
   * those other events.
   *
   * This is done within the RegionEntry synchronization lock.
   */
  boolean dispatchListenerEvents(EntryEventImpl event) throws InterruptedException;

  /**
   * Used to mark an LRU entry as having been recently used.
   */
  void setRecentlyUsed(RegionEntryContext context); // same method as on EvictionNode interface

  void updateStatsForGet(boolean hit, long time);

  /**
   * Resets any entry state as needed for a transaction that did a destroy to this entry.
   *
   * @param currentTime Current Cache Time.
   */
  void txDidDestroy(long currentTime);

  void resetCounts() throws InternalStatisticsDisabledException;

  /**
   * this is done instead of removePhase2 if the entry needs to be kept for concurrency control
   *
   * @param region the region holding the entry
   * @param version whether the operation is from another member or local
   */
  void makeTombstone(InternalRegion region, VersionTag version) throws RegionClearedException;

  /**
   * Mark this entry as being in the process of removal from the map that contains it by setting its
   * value to Token.REMOVED_PHASE1. An entry in this state may be resurrected by changing the value
   * under synchronization prior to the entry executing removePhase2.
   *
   * @param region the region
   * @param clear - if we removing this entry as a result of a region clear.
   * @throws RegionClearedException If operation got aborted due to a clear
   *
   */
  void removePhase1(InternalRegion region, boolean clear) throws RegionClearedException;

  /**
   * Mark this entry as having been removed from the map that contained it by setting its value to
   * Token.REMOVED_PHASE2
   */
  void removePhase2();

  /**
   * Returns true if this entry does not exist. This is true if removal has started (value ==
   * Token.REMOVED_PHASE1) or has completed (value == Token.REMOVED_PHASE2) or is a TOMBSTONE.
   */
  boolean isRemoved();

  /**
   * Returns true if this entry does not exist and will not be resurrected (value ==
   * Token.REMOVED_PHASE2)
   */
  boolean isRemovedPhase2();

  /**
   * Returns true if this entry is a tombstone, meaning that it has been removed but is being
   * retained for concurrent modification detection. Tombstones may be resurrected just like an
   * entry that is in REMOVED_PHASE1 state.
   */
  boolean isTombstone();

  /**
   * Fill in value, and isSerialized fields in this entry object (used for getInitialImage and sync
   * recovered) Also sets the lastModified time in cacheTime. Only called for DistributedRegions.
   *
   * <p>
   * This method returns tombstones so that they can be transferred with the initial image.
   *
   * @return false if map entry not found
   *
   * @see InitialImageOperation.RequestImageMessage#chunkEntries
   *
   * @since GemFire 3.2.1
   */
  boolean fillInValue(InternalRegion region,
      @Retained(ABSTRACT_REGION_ENTRY_FILL_IN_VALUE) Entry entry, ByteArrayDataInput in,
      DistributionManager distributionManager, final Version version);

  /**
   * Returns true if this entry has overflowed to disk.
   *
   * @param diskPosition if overflowed then the position of the value is set in dp
   */
  boolean isOverflowedToDisk(InternalRegion region, DistributedRegion.DiskPosition diskPosition);

  /**
   * Gets the key for this entry.
   */
  Object getKey();

  /**
   * Gets the value for this entry. For DiskRegions, faults in value and returns it
   */
  Object getValue(RegionEntryContext context);

  /**
   * Just like getValue but the result may be a retained off-heap reference.
   */
  @Retained
  Object getValueRetain(RegionEntryContext context);

  @Released
  void setValue(RegionEntryContext context, @Unretained Object value) throws RegionClearedException;

  /**
   * This flavor of setValue was added so that the event could be passed down to Helper.writeToDisk.
   * The event can be used to cache the serialized form of the value we are writing. See bug 43781.
   */
  void setValue(RegionEntryContext context, Object value, EntryEventImpl event)
      throws RegionClearedException;

  /**
   * Obtain, retain and return the value of this entry. WARNING: if a StoredObject is returned and
   * it has a refCount then the caller MUST make sure that {@link StoredObject#release()} before the
   * returned object is garbage collected.
   *
   * This is only retained in off-heap subclasses. However, it's marked as Retained here so that
   * callers are aware that the value may be retained.
   *
   * @param decompress if true returned value will be decompressed if it is compressed
   * @return possible OFF_HEAP_OBJECT (caller must release)
   */
  @Retained
  Object getValueRetain(RegionEntryContext context, boolean decompress);

  /**
   * Gets the value field of this entry.
   */
  @Unretained
  Object getValue();

  /**
   * Returns a tokenized form of the value. If the value can not be represented as a token then
   * Token.NOT_A_TOKEN is returned.
   */
  Token getValueAsToken();

  /**
   * Set the value of this entry and perform checks to see if a GC task needs to be scheduled.
   *
   * @param value the new value for this entry
   * @param event the cache event that caused this change
   * @throws RegionClearedException thrown if the region is concurrently cleared
   */
  void setValueWithTombstoneCheck(@Unretained Object value, EntryEvent event)
      throws RegionClearedException;

  /**
   * Returns the value as stored by the RegionEntry implementation. For instance, if compressed this
   * value would be the compressed form.
   *
   * @since GemFire 8.0
   */
  @Retained
  Object getTransformedValue();

  /**
   * Returns the value of an entry as it resides in the VM.
   *
   * @return the value or EntryEvent.NOT_AVAILABLE token if it's not in the VM or null if the entry
   *         doesn't exist.
   *
   * @see InternalRegion#getValueInVM
   */
  Object getValueInVM(RegionEntryContext context);

  /**
   * Returns the value of an entry as it resides on disk. For testing purposes only.
   *
   * @see InternalRegion#getValueOnDisk
   */
  Object getValueOnDisk(InternalRegion region) throws EntryNotFoundException;

  /**
   * Returns the value of an entry as it resides on buffer or disk. For asynch mode a value is not
   * immediately written to the disk & so checking in asynch buffers is needed .For testing purposes
   * only.
   *
   * @see InternalRegion#getValueOnDisk
   */

  Object getValueOnDiskOrBuffer(InternalRegion region) throws EntryNotFoundException;


  /**
   * Used to modify an existing RegionEntry when processing the values obtained during a
   * getInitialImage.
   */
  boolean initialImagePut(InternalRegion region, long lastModified, Object newValue,
      boolean wasRecovered, boolean acceptedVersionTag) throws RegionClearedException;

  /**
   * Used to initialize a created RegionEntry when processing the values obtained during a
   * getInitialImage.
   *
   * <p>
   * put if LOCAL_INVALID and nonexistent<br>
   * put if INVALID and nonexistent, recovered, or LOCAL_INVALID<br>
   * put if valid and nonexistent, recovered, or LOCAL_INVALID
   *
   * <p>
   * REGION_INVALIDATED: (special case)<br>
   * If the region itself has been invalidated since getInitialImage<br>
   * started, and newValue is LOCAL_INVALID or valid,<br>
   * then force creation of INVALID key if currently nonexistent<br>
   * or invalidate if current recovered.<br>
   *
   * <p>
   * must write-synchronize to protect against puts from other<br>
   * threads running this method
   */
  boolean initialImageInit(InternalRegion region, long lastModified, Object newValue,
      boolean create, boolean wasRecovered, boolean acceptedVersionTag)
      throws RegionClearedException;

  /**
   * @param expectedOldValue only succeed with destroy if current value is equal to expectedOldValue
   * @param forceDestroy true if caller just added this entry because we are inTokenMode and we need
   *        to "create" a destroyed entry to mark the destroy
   * @return true if destroy was done; false if not
   */
  @Released
  boolean destroy(InternalRegion region, EntryEventImpl event, boolean inTokenMode,
      boolean cacheWrite, @Unretained Object expectedOldValue, boolean forceDestroy,
      boolean removeRecoveredEntry)
      throws CacheWriterException, EntryNotFoundException, TimeoutException, RegionClearedException;

  /**
   * @return true if entry's value came from a netsearch
   * @since GemFire 6.5
   */
  boolean getValueWasResultOfSearch();

  /**
   * @param value true if entry's value should be marked as having been the result of a netsearch.
   * @since GemFire 6.5
   */
  void setValueResultOfSearch(boolean value);

  /**
   * Get the serialized bytes from disk. This method only looks for the value on the disk, ignoring
   * heap data.
   *
   * @param region the persistent region
   * @return the serialized value from disk
   * @since GemFire 5.7
   */
  Object getSerializedValueOnDisk(InternalRegion region);

  /**
   * Gets the value for this entry. For DiskRegions, unlike {@link #getValue(RegionEntryContext)}
   * this will not fault in the value rather return a temporary copy.
   */
  Object getValueInVMOrDiskWithoutFaultIn(InternalRegion region);

  /**
   * Gets the value for this entry. For DiskRegions, unlike {@link #getValue(RegionEntryContext)}
   * this will not fault in the value rather return a temporary copy. The value returned will be
   * kept off heap (and compressed) if possible.
   */
  @Retained
  Object getValueOffHeapOrDiskWithoutFaultIn(InternalRegion region);

  /**
   * RegionEntry is underUpdate as soon as RegionEntry lock is help by an update thread to put a new
   * value for an existing key. This is used during query on the region to verify index entry with
   * current region entry.
   *
   * @return true if RegionEntry is under update during cache put operation.
   */
  boolean isUpdateInProgress();

  /**
   * Sets RegionEntry updateInProgress flag when put is happening for an existing Region.Entry.
   * Called ONLY in {@link AbstractRegionMap}.
   */
  void setUpdateInProgress(final boolean underUpdate);

  /**
   * Event containing this RegionEntry is being passed through dispatchListenerEvent for
   * CacheListeners under RegionEntry lock. This is used during deserialization for a
   * VMCacheSerializable value contained by this RegionEntry.
   *
   * @return true if Event is being dispatched to CacheListeners.
   */
  boolean isCacheListenerInvocationInProgress();

  /**
   * Sets RegionEntry isCacheListenerInvoked flag when put is happening for a Region.Entry. Called
   * ONLY in {@link InternalRegion#dispatchListenerEvent}.
   */
  void setCacheListenerInvocationInProgress(final boolean isListenerInvoked);

  /**
   * Returns true if the entry value is null.
   */
  boolean isValueNull();

  /**
   * Returns true if the entry value is equal to {@link Token#INVALID} or
   * {@link Token#LOCAL_INVALID}.
   */
  boolean isInvalid();

  /**
   * Returns true if the entry value is equal to {@link Token#DESTROYED}.
   */
  boolean isDestroyed();

  /**
   * Returns true if the entry value is equal to {@link Token#DESTROYED} or
   * {@link Token#REMOVED_PHASE1} or {@link Token#REMOVED_PHASE2} or {@link Token#TOMBSTONE}.
   */
  boolean isDestroyedOrRemoved();

  /**
   * Returns true if the entry value is equal to {@link Token#DESTROYED} or
   * {@link Token#REMOVED_PHASE1} or {@link Token#REMOVED_PHASE2}.
   */
  boolean isDestroyedOrRemovedButNotTombstone();

  /**
   * @see Token#isInvalidOrRemoved(Object)
   */
  boolean isInvalidOrRemoved();

  /**
   * Sets the entry value to null.
   */
  void setValueToNull();

  void returnToPool();

  boolean isInUseByTransaction();

  /**
   * Increments the number of transactions that are currently referencing this node.
   */
  void incRefCount();

  /**
   * Decrements the number of transactions that are currently referencing this node.
   *
   * @param region the local region that owns this region entry; null if no local region owner
   */
  void decRefCount(EvictionList lruList, InternalRegion region);

  /**
   * Clear the number of transactions that are currently referencing this node and returns to LRU
   * list
   */
  void resetRefCount(EvictionList lruList);

  @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE)
  Object prepareValueForCache(RegionEntryContext context, Object value, boolean isEntryUpdate);

  @Retained(ABSTRACT_REGION_ENTRY_PREPARE_VALUE_FOR_CACHE)
  Object prepareValueForCache(RegionEntryContext context, Object value, EntryEventImpl event,
      boolean isEntryUpdate);

  boolean isEvicted();
}
