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

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.geode.annotations.internal.MutableForTesting;
import org.apache.geode.internal.InternalDataSerializer;
import org.apache.geode.internal.VersionedDataSerializable;
import org.apache.geode.internal.serialization.Version;

/**
 * RVV exceptions are part of a RegionVersionVector. They are held by RegionVersionHolders.
 * <p>
 *
 * An RVV exception represents a missing range of versions from a member. This is represented as a
 * pair of version numbers: the last version we've received from the member and the next version
 * we've received from the member. The span of versions between (but not including) these two
 * numbers are the versions that are missing.
 * <p>
 *
 * RVVException also tracks the scattering of versions we've received that fall within the range of
 * the exception. As these missing versions are received the RVVException coalesces the range. If
 * isFilled() returns true after adding a missing version to the RVVException, the hole has been
 * filled and the RVVException is no longer needed.
 * <p>
 *
 * New exceptions are common to see as operations arrive from parallel threads operating on the same
 * region. These exceptions are soon mended and disappear.
 * <p>
 *
 * Old exceptions indicate that we missed something that we are unlikely to receive without asking
 * for it.
 * <p>
 *
 * RVVException currently depends on external synchronization. Typically the RegionVersionHolder
 * that holds the exception is locked while accessing its RVVExceptions. This is what is done in
 * RegionVersionVector.
 *
 */
abstract class RVVException
    implements Comparable<RVVException>, Cloneable, VersionedDataSerializable {
  private static final long serialVersionUID = 2021977010704105114L;

  @MutableForTesting
  protected static boolean UseTreeSetsForTesting = false;

  /**
   * The maximum version span that can be represented by a bitset RVVException. If the span is
   * greater than this we use the version of RVVException that collects "received versions" in a
   * regular collection.
   */
  protected static final long RVV_MAX_BITSET_SPAN = 128 * 8; // 128 bytes gives a span of 1k
                                                             // versions

  long previousVersion;
  long nextVersion;


  /**
   * Create an exception to represent missing versions
   *
   * @param previousVersion The previous version before the first missing version
   * @param nextVersion The next received version after the last missing version
   */
  static RVVException createException(long previousVersion, long nextVersion) {
    return createException(previousVersion, nextVersion, 0);
  }

  /** Use this method to create a new RVVException */
  static RVVException createException(long previousVersion, long nextVersion,
      long initialExceptionCount) {
    // arbitrary cutoff of 100 bytes to use a treeSet instead of bitSet
    // But if we are deserializing an exception too many received versions use a
    // bitset anyway.
    long delta = nextVersion - previousVersion;
    if (UseTreeSetsForTesting
        || (delta > RVV_MAX_BITSET_SPAN && initialExceptionCount * 512 < delta)) {
      return new RVVExceptionT(previousVersion, nextVersion);
    }
    return new RVVExceptionB(previousVersion, nextVersion);
  }

  RVVException(long previousVersion, long nextVersion) {
    this.previousVersion = previousVersion;
    this.nextVersion = nextVersion;
  }



  /**
   * RegionVersionHolder.fromData() calls this to create an exception
   */
  static RVVException createException(DataInput in) throws IOException {
    long previousVersion = InternalDataSerializer.readUnsignedVL(in);
    int size = (int) InternalDataSerializer.readUnsignedVL(in);
    long last = previousVersion;
    long[] versions = new long[(int) size];
    for (int i = 0; i < size; i++) {
      long delta = InternalDataSerializer.readUnsignedVL(in);
      long value = delta + last;
      versions[i] = value;
      last = value;
    }
    long delta = InternalDataSerializer.readUnsignedVL(in);
    long nextVersion = last + delta;
    RVVException result = createException(previousVersion, nextVersion, size);

    for (int i = 0; i < size; i++) {
      result.addReceived(versions[i]);
    }
    return result;
  }


  /** has the given version been recorded as having been received? */
  public abstract boolean contains(long version);

  /** return false if any revisions have been recorded in the range of this exception */
  public abstract boolean isEmpty();

  /** internal method to add a new version to the received-versions collection */
  protected abstract void addReceived(long version);

  @Override
  public void toData(DataOutput out) throws IOException {
    InternalDataSerializer.writeUnsignedVL(this.previousVersion, out);
    writeReceived(out);
  }

  /**
   * add a received version
   */
  public abstract void add(long receivedVersion);

  /**
   * returns true if the missing versions that this exception represents have all been received
   */
  public boolean isFilled() {
    return this.previousVersion + 1 >= this.nextVersion;
  }

  @Override
  public abstract RVVException clone();

  /*
   * (non-Javadoc)
   *
   * @see java.lang.Comparable#compareTo(java.lang.Object)
   */
  @Override
  public int compareTo(RVVException o) {
    long thisVal = this.previousVersion;
    long anotherVal = o.previousVersion;
    return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1));
  }

  /** Test hook - compare two exceptions */
  public boolean sameAs(RVVException other) {
    return (this.previousVersion == other.previousVersion)
        && (this.nextVersion == other.nextVersion);
  }

  @Override
  public boolean equals(Object obj) {
    throw new UnsupportedOperationException("change the test to use sameAs");
  }

  @Override
  public int hashCode() {
    throw new UnsupportedOperationException("this class does not support hashing at this time");
  }

  protected abstract void writeReceived(DataOutput out) throws IOException;

  public abstract ReceivedVersionsReverseIterator receivedVersionsReverseIterator();

  public abstract long getHighestReceivedVersion();

  public abstract class ReceivedVersionsReverseIterator {

    abstract boolean hasNext();

    abstract long next();

    abstract void remove();

  }

  @Override
  public void fromData(DataInput in) throws IOException, ClassNotFoundException {}

  @Override
  public Version[] getSerializationVersions() {
    return null;
  }

  public boolean shouldChangeForm() {
    return false;
  }

  public RVVException changeForm() {
    throw new IllegalStateException("Should not be called");
  }
}
