/*=========================================================================
 * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
 * This product is protected by U.S. and international copyright
 * and intellectual property laws. Pivotal products are covered by
 * one or more patents listed at http://www.pivotal.io/patents.
 *=========================================================================
 */
/**
 * 
 */
package javaobject;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Properties;
import java.util.Arrays;

import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
import com.gemstone.gemfire.DataSerializable;
import com.gemstone.gemfire.Delta;
import com.gemstone.gemfire.DataSerializer;
import com.gemstone.gemfire.cache.Declarable;
import com.gemstone.gemfire.InvalidDeltaException;
import com.gemstone.gemfire.Instantiator;

/**
 * Sample test class which implements Delta.
 * 
 * @since 6.1
 */
public class DeltaTestImpl implements DataSerializable, Delta, Declarable {

  static {
     Instantiator.register(new Instantiator(DeltaTestImpl.class, (byte) 30) {
     public DataSerializable newInstance() {
        return new DeltaTestImpl();
     }
   });
  }
  
  private static final byte INT_MASK      = 0x1;
  private static final byte STR_MASK      = 0x2;
  private static final byte DOUBLE_MASK   = 0x4;
  private static final byte BYTE_ARR_MASK = 0x8;
  private static final byte TEST_OBJ_MASK = 0x10;
  private static final byte COMPLETE_MASK = 0x1F;  
  
  /*****************************************************************************
   * Below fields are not part of standard Delta implementation but are used for
   * testing purpose.
   */
  public static final String ERRONEOUS_STRING_FOR_FROM_DELTA = "ERRONEOUS_STRING";
  public static final int ERRONEOUS_INT_FOR_TO_DELTA = -101;
  private static long fromDeltaInvokations;
  private static long toDeltaInvokations;
  private static long toDeltaFailure;
  private static long fromDeltaFailure;
  public static boolean NEED_TO_RESET_T0_DELTA = true;
  /** *********************************************************************** */
  
  // Actual data fields of this instance.
  private int intVar = 0;                          // 0000 0001
  private String str = "";                         // 0000 0010
  private Double doubleVar = new Double(0);        // 0000 0100
  private byte[] byteArr = new byte[1];            // 0000 1000
  private TestObject1 testObj = new TestObject1(); // 0001 0000

  /**
   * Indicates the fields containing delta.
   */
  private byte deltaBits = 0x0;

  private boolean hasDelta = false;

  public DeltaTestImpl() {
  }

  public DeltaTestImpl(int intVal, String str) {
    this.intVar = intVal;
    this.str = str;
  }

  public DeltaTestImpl(int intVal, String string, Double doubleVal,
      byte[] bytes, TestObject1 testObj) {
    this.intVar = intVal;
    this.str = string;
    this.doubleVar = doubleVal;
    this.byteArr = bytes;
    this.testObj = testObj;
  }

  public void resetDeltaStatus() {
    this.deltaBits = 0x0;
    this.hasDelta = false;
  }

  public byte[] getByteArr() {
    return byteArr;
  }

  public void setByteArr(byte[] bytes) {
    this.byteArr = bytes;
    this.deltaBits |= BYTE_ARR_MASK;
    this.hasDelta = true;
  }

  public Double getDoubleVar() {
    return doubleVar;
  }

  public void setDoubleVar(Double doubleVar) {
    this.doubleVar = doubleVar;
    this.deltaBits |= DOUBLE_MASK;
    this.hasDelta = true;
  }

  public int getIntVar() {
    return intVar;
  }

  public void setIntVar(int intVar) {
    this.intVar = intVar;
    this.deltaBits |= INT_MASK;
    this.hasDelta = true;
  }

  public String getStr() {
    return str;
  }

  public void setStr(String str) {
    this.str = str;
    this.deltaBits |= STR_MASK;
    this.hasDelta = true;
  }

  public TestObject1 getTestObj() {
    return testObj;
  }

  public void setTestObj(TestObject1 testObj) {
    this.testObj = testObj;
    this.deltaBits |= TEST_OBJ_MASK;
    this.hasDelta = true;
  }

  /*****************************************************************************
   * Below methods are not part of standard Delta implementation but are used
   * for testing purpose.
   */
  public static void resetDeltaInvokationCounters() {
    resetToDeltaCounter();
    resetFromDeltaCounter();
    resetFailureCounter();
  }

  public static void resetToDeltaCounter() {
    toDeltaInvokations = 0;
  }

  public static void resetFromDeltaCounter() {
    fromDeltaInvokations = 0;
  }

  public static void resetFailureCounter() {
    toDeltaFailure = 0;
    fromDeltaFailure = 0;
  }

  public static Boolean deltaFeatureUsed() {
    return (toDeltaInvokations > 0) || (fromDeltaInvokations > 0);
  }

  public static Boolean toDeltaFeatureUsed() {
    return (toDeltaInvokations > 0);
  }

  public static Long getFromDeltaInvokations() {
    return fromDeltaInvokations;
  }

  public static Long getToDeltaInvokations() {
    return toDeltaInvokations;
  }

  public static Boolean fromDeltaFeatureUsed() {
    return (fromDeltaInvokations > 0);
  }

  public static Boolean isFromDeltaFailure() {
    return (fromDeltaFailure > 0);
  }

  public static Boolean isToDeltaFailure() {
    return (toDeltaFailure > 0);
  }

  public static Long getFromDeltaFailures() {
    return fromDeltaFailure;
  }

  public static Long getToDeltaFailures() {
    return toDeltaFailure;
  }
  
  protected void checkInvalidString(String str) {
    if (ERRONEOUS_STRING_FOR_FROM_DELTA.equals(str)) {
      fromDeltaFailure++;
      throw new InvalidDeltaException("Delta could not be applied. "
          + this);
    }
  }

  protected void checkInvalidInt(int intVal) {
    if (ERRONEOUS_INT_FOR_TO_DELTA == intVal) {
      toDeltaFailure++;
      throw new InvalidDeltaException("Delta could not be extracted. "
          + this);
    }
  }

  protected void checkInvalidInt2(int intVal) {}
  /** ********************************************************************** */

  public String toString() {
    StringBuffer bytes = new StringBuffer("");
    if (byteArr != null) {
      for (int i = 0; i < byteArr.length; i++) {
        bytes.append(byteArr[i]);
      }
    }
    return "DeltaTestImpl[hasDelta=" + this.hasDelta + ",int=" + this.intVar
        + ",double=" + this.doubleVar + ",str=" + this.str + ",bytes={"
        + bytes.toString() + "},testObj="
        + ((this.testObj != null) ? this.testObj.hashCode() : "") + "]";
  }

  public boolean equals(Object other) {
    if (other == null || !(other instanceof DeltaTestImpl)) {
      return false;
    }
    DeltaTestImpl delta = (DeltaTestImpl)other;
    if (this.intVar == delta.intVar && this.doubleVar.equals(delta.doubleVar)
        && Arrays.equals(this.byteArr, delta.byteArr)
        && this.str.equals(delta.str)) {
      return true;
    }
    return false;
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.gemstone.gemfire.Delta#fromDelta(java.io.DataInput)
   */
  public void fromDelta(DataInput in) throws IOException {
    try {
      
      fromDeltaInvokations++;
      boolean tempHasDelta = false;
      byte tempDeltaBits = this.deltaBits;
      byte[] tempByteArr = this.byteArr;
      int tempIntVar = this.intVar;
      double tempDoubleVar = this.doubleVar;
      String tempStr = this.str;
      TestObject1 tempTestObj = this.testObj;

      tempDeltaBits = DataSerializer.readByte(in);
      if (tempDeltaBits != 0) {
        tempHasDelta = true;
        if ((tempDeltaBits & INT_MASK) == INT_MASK) {
          tempIntVar = DataSerializer.readPrimitiveInt(in);
          checkInvalidInt2(tempIntVar);
        }
        if ((tempDeltaBits & STR_MASK) == STR_MASK) {
          tempStr = DataSerializer.readString(in);
          checkInvalidString(tempStr); // Simulates exception
        }
        if ((tempDeltaBits & DOUBLE_MASK) == DOUBLE_MASK) {
          tempDoubleVar = DataSerializer.readDouble(in);
        }
        if ((tempDeltaBits & BYTE_ARR_MASK) == BYTE_ARR_MASK) {
          //tempByteArr = DataSerializer.readByteArray(in);
	  tempByteArr=(byte[])DataSerializer.readObject(in);
        }
        if ((tempDeltaBits & TEST_OBJ_MASK) == TEST_OBJ_MASK) {
          tempTestObj = (TestObject1)DataSerializer.readObject(in);
        }
        if ((deltaBits | COMPLETE_MASK) != COMPLETE_MASK) {
          throw new IllegalArgumentException("Unknown field code: "
              + tempDeltaBits);
        }
      }
      if (tempHasDelta) {
        //this.hasDelta = true;
        //this.deltaBits = tempDeltaBits;
        this.intVar = tempIntVar;
        this.str = tempStr;
        this.doubleVar = tempDoubleVar;
        this.byteArr = tempByteArr;
        this.testObj = tempTestObj;
      }
    }
    catch (IOException e) {
      GemFireCacheImpl.getInstance().getLogger().warning(
          "DeltaTestImpl.fromDelta(): " + e);
      throw e;
    }
    catch (IllegalArgumentException iae) {
      GemFireCacheImpl.getInstance().getLogger().warning(
          "DeltaTestImpl.fromDelta(): " + iae);
      throw new InvalidDeltaException(iae);
    }
    catch (ClassNotFoundException cnfe) {
      GemFireCacheImpl.getInstance().getLogger().warning(
          "DeltaTestImpl.fromDelta(): " + cnfe);
      throw new InvalidDeltaException(cnfe);
    }
  }
  
  /*
   * (non-Javadoc)
   * 
   * @see com.gemstone.gemfire.Delta#hasDelta()
   */
  public boolean hasDelta() {
    return this.hasDelta;
  }

  /*
   * (non-Javadoc)
   * 
   * @see com.gemstone.gemfire.Delta#toDelta(java.io.DataOutput)
   */
  public void toDelta(DataOutput out) throws IOException {
    try {
      toDeltaInvokations++;
      DataSerializer.writeByte(this.deltaBits, out);

      if (deltaBits != 0) {
        if ((deltaBits & INT_MASK) == INT_MASK) {
          DataSerializer.writePrimitiveInt(this.intVar, out);
          checkInvalidInt(this.intVar); // Simulates exception
        }
        if ((deltaBits & STR_MASK) == STR_MASK) {
          DataSerializer.writeString(this.str, out);
        }
        if ((deltaBits & DOUBLE_MASK) == DOUBLE_MASK) {
          DataSerializer.writeDouble(this.doubleVar, out);
        }
        if ((deltaBits & BYTE_ARR_MASK) == BYTE_ARR_MASK) {
          DataSerializer.writeByteArray(this.byteArr, out);
        }
        if ((deltaBits & TEST_OBJ_MASK) == TEST_OBJ_MASK) {
          DataSerializer.writeObject(this.testObj, out);
        }
        if ((deltaBits | COMPLETE_MASK) != COMPLETE_MASK) {
          throw new IllegalArgumentException("Unknown field code: " + deltaBits);
        }
      }
    }
    catch (IOException ioe) {
      GemFireCacheImpl.getInstance().getLogger().warning(
          "DeltaTestImpl.toDelta(): " + ioe);
      throw ioe;
    }
    catch (IllegalArgumentException iae) {
      GemFireCacheImpl.getInstance().getLogger().warning(
          "DeltaTestImpl.toDelta(): " + iae);
      throw new InvalidDeltaException(iae);
    }
    finally {
      if (NEED_TO_RESET_T0_DELTA) {// No need to reset if secondary needs to
                                    // send delta again upon receiving
                                    // forceReattemptException
        this.deltaBits = 0x0;
        this.hasDelta = false;
      } 
    }
  }

  public void fromData(DataInput in) throws IOException, ClassNotFoundException {
    //this.deltaBits = DataSerializer.readByte(in);
    this.intVar = DataSerializer.readPrimitiveInt(in);
    this.str = DataSerializer.readString(in);
    this.doubleVar = DataSerializer.readDouble(in);
    this.byteArr = (byte[])DataSerializer.readObject(in);
    this.testObj = (TestObject1)DataSerializer.readObject(in);
    //if (deltaBits != 0) {
    //  this.hasDelta = true;
    //}
  }

  public void toData(DataOutput out) throws IOException {
    //DataSerializer.writeByte(this.deltaBits, out);
    DataSerializer.writePrimitiveInt(this.intVar, out);
    DataSerializer.writeString(this.str, out);
    DataSerializer.writeDouble(this.doubleVar, out);
    DataSerializer.writeObject(this.byteArr, out);
    DataSerializer.writeObject(this.testObj, out);
  }
  
  public void init(Properties props) {
  }
}
