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

import org.apache.geode.internal.HeapDataOutputStream;
import org.apache.geode.internal.InternalDataSerializer;
import org.apache.geode.internal.offheap.StoredObject;
import org.apache.geode.internal.offheap.annotations.Unretained;
import org.apache.geode.internal.serialization.Version;
import org.apache.geode.pdx.PdxInstance;
import org.apache.geode.pdx.PdxSerializable;
import org.apache.geode.pdx.PdxSerializationException;
import org.apache.geode.pdx.PdxSerializer;

public class ValueComparisonHelper {

  public static boolean checkEquals(@Unretained Object v1, @Unretained Object v2,
      boolean isCompressedOffHeap, InternalCache cache) {
    // need to give PdxInstance#equals priority
    if (v1 instanceof PdxInstance) {
      return checkPdxEquals((PdxInstance) v1, v2, cache);
    } else if (v2 instanceof PdxInstance) {
      return checkPdxEquals((PdxInstance) v2, v1, cache);
    } else if (v1 instanceof StoredObject) {
      return checkOffHeapEquals((StoredObject) v1, v2, cache);
    } else if (v2 instanceof StoredObject) {
      return checkOffHeapEquals((StoredObject) v2, v1, cache);
    } else if (v1 instanceof CachedDeserializable) {
      return checkCDEquals((CachedDeserializable) v1, v2, isCompressedOffHeap, cache);
    } else if (v2 instanceof CachedDeserializable) {
      return checkCDEquals((CachedDeserializable) v2, v1, isCompressedOffHeap, cache);
    } else {
      return basicEquals(v1, v2);
    }
  }

  static boolean basicEquals(Object v1, Object v2) {
    if (v2 != null) {
      if (v2.getClass().isArray()) {
        // fix for 52093
        if (v2 instanceof byte[]) {
          if (v1 instanceof byte[]) {
            return Arrays.equals((byte[]) v2, (byte[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof Object[]) {
          if (v1 instanceof Object[]) {
            return Arrays.deepEquals((Object[]) v2, (Object[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof int[]) {
          if (v1 instanceof int[]) {
            return Arrays.equals((int[]) v2, (int[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof long[]) {
          if (v1 instanceof long[]) {
            return Arrays.equals((long[]) v2, (long[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof boolean[]) {
          if (v1 instanceof boolean[]) {
            return Arrays.equals((boolean[]) v2, (boolean[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof short[]) {
          if (v1 instanceof short[]) {
            return Arrays.equals((short[]) v2, (short[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof char[]) {
          if (v1 instanceof char[]) {
            return Arrays.equals((char[]) v2, (char[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof float[]) {
          if (v1 instanceof float[]) {
            return Arrays.equals((float[]) v2, (float[]) v1);
          } else {
            return false;
          }
        } else if (v2 instanceof double[]) {
          if (v1 instanceof double[]) {
            return Arrays.equals((double[]) v2, (double[]) v1);
          } else {
            return false;
          }
        }
        // fall through and call equals method
      }
      return v2.equals(v1);
    } else {
      return v1 == null;
    }
  }

  /**
   * This method fixes bug 43643
   */
  private static boolean checkPdxEquals(PdxInstance pdx, Object obj, InternalCache cache) {
    if (!(obj instanceof PdxInstance)) {
      // obj may be a CachedDeserializable in which case we want to convert it to a PdxInstance even
      // if we are not readSerialized.
      if (obj instanceof CachedDeserializable) {
        CachedDeserializable cdObj = (CachedDeserializable) obj;
        if (!cdObj.isSerialized()) {
          // obj is actually a byte[] which will never be equal to a PdxInstance
          return false;
        }
        Object cdVal = cdObj.getValue();
        if (cdVal instanceof byte[]) {
          byte[] cdValBytes = (byte[]) cdVal;
          PdxInstance pi = InternalDataSerializer.readPdxInstance(cdValBytes, cache);
          if (pi != null) {
            return pi.equals(pdx);
          } else {
            // since obj is serialized as something other than pdx it must not equal our pdx
            return false;
          }
        } else {
          // remove the cd wrapper so that obj is the actual value we want to compare.
          obj = cdVal;
        }
      }
      if (obj != null && obj.getClass().getName().equals(pdx.getClassName())) {
        PdxSerializer pdxSerializer;
        if (obj instanceof PdxSerializable) {
          pdxSerializer = null;
        } else {
          pdxSerializer = cache.getPdxSerializer();
        }
        if (pdxSerializer != null || obj instanceof PdxSerializable) {
          // try to convert obj to a PdxInstance
          HeapDataOutputStream hdos = new HeapDataOutputStream(Version.CURRENT);
          try {
            if (InternalDataSerializer.autoSerialized(obj, hdos)
                || InternalDataSerializer.writePdx(hdos, cache, obj, pdxSerializer)) {
              PdxInstance pi = InternalDataSerializer.readPdxInstance(hdos.toByteArray(), cache);
              if (pi != null) {
                obj = pi;
              }
            }
          } catch (IOException | PdxSerializationException ignore) {
            // we are not able to convert it so just fall through
          }
        }
      }
    }
    return basicEquals(obj, pdx);
  }

  private static boolean checkOffHeapEquals(@Unretained StoredObject ohVal, @Unretained Object obj,
      InternalCache cache) {
    if (ohVal.isSerializedPdxInstance()) {
      PdxInstance pi = InternalDataSerializer.readPdxInstance(ohVal.getSerializedValue(), cache);
      return ValueComparisonHelper.checkPdxEquals(pi, obj, cache);
    }
    if (obj instanceof StoredObject) {
      return ohVal.checkDataEquals((StoredObject) obj);
    } else {
      byte[] serializedObj;
      if (obj instanceof CachedDeserializable) {
        CachedDeserializable cdObj = (CachedDeserializable) obj;
        if (!ohVal.isSerialized()) {
          assert cdObj.isSerialized();
          return false;
        }
        serializedObj = cdObj.getSerializedValue();
      } else if (obj instanceof byte[]) {
        if (ohVal.isSerialized()) {
          return false;
        }
        serializedObj = (byte[]) obj;
      } else {
        if (!ohVal.isSerialized()) {
          return false;
        }
        if (obj == null || obj == Token.NOT_AVAILABLE || Token.isInvalidOrRemoved(obj)) {
          return false;
        }
        serializedObj = EntryEventImpl.serialize(obj);
      }
      return ohVal.checkDataEquals(serializedObj);
    }
  }

  private static boolean checkCDEquals(CachedDeserializable cd, Object obj,
      boolean isCompressedOffHeap, InternalCache cache) {
    if (!cd.isSerialized()) {
      // cd is an actual byte[].
      byte[] ba2;
      if (obj instanceof CachedDeserializable) {
        CachedDeserializable cdObj = (CachedDeserializable) obj;
        if (cdObj.isSerialized()) {
          return false;
        }
        ba2 = (byte[]) cdObj.getDeserializedForReading();
      } else if (obj instanceof byte[]) {
        ba2 = (byte[]) obj;
      } else {
        return false;
      }
      byte[] ba1 = (byte[]) cd.getDeserializedForReading();
      return Arrays.equals(ba1, ba2);
    }
    Object cdVal = cd.getValue();
    if (cdVal instanceof byte[]) {
      if (obj == null || obj == Token.NOT_AVAILABLE || Token.isInvalidOrRemoved(obj)) {
        return false;
      }
      byte[] cdValBytes = (byte[]) cdVal;
      PdxInstance pi = InternalDataSerializer.readPdxInstance(cdValBytes, cache);
      if (pi != null) {
        return ValueComparisonHelper.checkPdxEquals(pi, obj, cache);
      }
      if (isCompressedOffHeap) {
        // fix for bug 52248
        byte[] serializedObj;
        if (obj instanceof CachedDeserializable) {
          serializedObj = ((CachedDeserializable) obj).getSerializedValue();
        } else {
          serializedObj = EntryEventImpl.serialize(obj);
        }
        return Arrays.equals(cdValBytes, serializedObj);
      } else {
        /*
         * To be more compatible with previous releases do not compare the serialized forms here.
         * Instead deserialize and call the equals method.
         */
        Object deserializedObj;
        if (obj instanceof CachedDeserializable) {
          deserializedObj = ((CachedDeserializable) obj).getDeserializedForReading();
        } else {
          // TODO OPTIMIZE: Before serializing all of obj we could get the top
          // level class name of cdVal and compare it to the top level class name of obj.
          deserializedObj = obj;
        }
        return basicEquals(deserializedObj, cd.getDeserializedForReading());
      }
    } else {
      // prefer object form
      if (obj instanceof CachedDeserializable) {
        // TODO OPTIMIZE: Before deserializing all of obj we could get the top
        // class name of cdVal and the top level class name of obj and compare.
        obj = ((CachedDeserializable) obj).getDeserializedForReading();
      }
      return basicEquals(cdVal, obj);
    }
  }
}
