/*
 * 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.entries;

import org.apache.geode.cache.EntryEvent;
import org.apache.geode.cache.EntryNotFoundException;
import org.apache.geode.distributed.internal.DistributionManager;
import org.apache.geode.internal.cache.DiskId;
import org.apache.geode.internal.cache.DistributedRegion;
import org.apache.geode.internal.cache.EntryBits;
import org.apache.geode.internal.cache.InitialImageOperation.Entry;
import org.apache.geode.internal.cache.InternalRegion;
import org.apache.geode.internal.cache.RegionClearedException;
import org.apache.geode.internal.cache.RegionEntry;
import org.apache.geode.internal.cache.RegionEntryContext;
import org.apache.geode.internal.cache.Token;
import org.apache.geode.internal.cache.versions.VersionTag;
import org.apache.geode.internal.offheap.annotations.Retained;
import org.apache.geode.internal.serialization.ByteArrayDataInput;
import org.apache.geode.internal.serialization.Version;

/**
 * Abstract implementation class of RegionEntry interface. This is adds Disk support behavior
 *
 * @since GemFire 3.5.1
 */
public abstract class AbstractOplogDiskRegionEntry extends AbstractDiskRegionEntry {

  protected AbstractOplogDiskRegionEntry(RegionEntryContext context, Object value) {
    super(context, value);
  }

  public abstract void setDiskId(RegionEntry oldRe);

  @Override
  public void removePhase1(InternalRegion region, boolean clear) throws RegionClearedException {
    synchronized (this) {
      Helper.removeFromDisk(this, region, clear);
      _removePhase1();
    }
  }

  @Override
  public void removePhase2() {
    Object syncObj = getDiskId();
    if (syncObj == null) {
      syncObj = this;
    }
    synchronized (syncObj) {
      super.removePhase2();
    }
  }

  @Override
  public boolean fillInValue(InternalRegion region, Entry entry, ByteArrayDataInput in,
      DistributionManager mgr, final Version version) {
    return Helper.fillInValue(this, entry, region.getDiskRegion(), mgr, in, region, version);
  }

  @Override
  public boolean isOverflowedToDisk(InternalRegion region,
      DistributedRegion.DiskPosition diskPosition) {
    return Helper.isOverflowedToDisk(this, region.getDiskRegion(), diskPosition, region);
  }

  @Override
  public Object getValue(RegionEntryContext context) {
    return Helper.faultInValue(this, (InternalRegion) context); // OFFHEAP returned to callers
  }

  @Override
  @Retained
  public Object getValueRetain(RegionEntryContext context) {
    return Helper.faultInValueRetain(this, (InternalRegion) context);
  }

  @Override
  public Object getValueInVMOrDiskWithoutFaultIn(InternalRegion region) {
    return Helper.getValueInVMOrDiskWithoutFaultIn(this, region);
  }

  @Retained
  @Override
  public Object getValueOffHeapOrDiskWithoutFaultIn(InternalRegion region) {
    return Helper.getValueOffHeapOrDiskWithoutFaultIn(this, region);
  }

  @Override
  public Object getValueOnDisk(InternalRegion region) throws EntryNotFoundException {
    return Helper.getValueOnDisk(this, region.getDiskRegion());
  }

  @Override
  public Object getSerializedValueOnDisk(InternalRegion region) throws EntryNotFoundException {
    return Helper.getSerializedValueOnDisk(this, region.getDiskRegion());
  }

  @Override
  public Object getValueOnDiskOrBuffer(InternalRegion region) throws EntryNotFoundException {
    // @todo darrel if value is Token.REMOVED || Token.DESTROYED throw
    // EntryNotFoundException
    return Helper.getValueOnDiskOrBuffer(this, region.getDiskRegion(), region);
  }

  @Override
  public DiskEntry getPrev() {
    return getDiskId().getPrev();
  }

  @Override
  public DiskEntry getNext() {
    return getDiskId().getNext();
  }

  @Override
  public void setPrev(DiskEntry v) {
    getDiskId().setPrev(v);
  }

  @Override
  public void setNext(DiskEntry v) {
    getDiskId().setNext(v);
  }

  /*
   * If detected a conflict event, persist region needs to persist both the golden copy and conflict
   * tag
   */
  @Override
  public void persistConflictingTag(InternalRegion region, VersionTag tag) {
    // only persist region needs to persist conflict tag
    Helper.updateVersionOnly(this, region, tag);
    setRecentlyUsed(region);
  }

  /**
   * Process a version tag. This overrides AbtractRegionEntry so we can check to see if the old
   * value was recovered from disk. If so, we don't check for conflicts.
   */
  @Override
  public void processVersionTag(EntryEvent cacheEvent) {
    DiskId did = getDiskId();
    boolean checkConflicts = true;
    if (did != null) {
      InternalRegion lr = (InternalRegion) cacheEvent.getRegion();
      if (lr != null && lr.getDiskRegion().isReadyForRecovery()) {
        synchronized (did) {
          checkConflicts = !EntryBits.isRecoveredFromDisk(did.getUserBits());
        }
      }
    }

    processVersionTag(cacheEvent, checkConflicts);
  }

  /**
   * Returns true if the DiskEntry value is equal to {@link Token#DESTROYED},
   * {@link Token#REMOVED_PHASE1}, or {@link Token#REMOVED_PHASE2}.
   */
  @Override
  public boolean isRemovedFromDisk() {
    return Token.isRemovedFromDisk(getValueAsToken());
  }

  // Do not add any instance variables to this class.
  // Instead add them to the DISK section of LeafRegionEntry.cpp.
}
