/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sdo.helper;

import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.helper.EqualityHelper;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.impl.HelperProvider;
import java.util.Iterator;
import java.util.List;
import org.eclipse.persistence.sdo.SDODataObject;
import org.eclipse.persistence.sdo.SDOProperty;
import org.eclipse.persistence.sdo.SDOSequence;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.sequenced.Setting;

/**
 * <p><b>Purpose</b>: A helper class for checking deep or shallow equality of DataObjects.</p>
 * <p>ChangeSummary is not in scope for equality checking.
 *
 * @see org.eclipse.persistence.sdo.SDODataObject
 * @since Oracle TopLink 11.1.1.0.0
 *
 */
public class SDOEqualityHelper implements EqualityHelper {

    /*
    References:
        SDO59-DeepCopy.doc
        SDO_Ref_BiDir_Relationships_DesignSpec.doc
        http://files.oraclecorp.com/content/MySharedFolders/ST%20Functional%20Specs/AS11gR1/TopLink/SDO/SDO_Ref_BiDir_Relationships_DesignSpec.doc

     09/12/06 - Add bidirectional property support in compareProperty()
     09/18/06 - remove shallow opposite property check - just return true if both objects are set and are DO's
     01/29/07 - #5852525 handle null properties with isSet=true
     04/11/07 - Implement Sequence functionality
    */

    /** hold the context containing all helpers so that we can preserve inter-helper relationships */
    private HelperContext aHelperContext;

    /**
     * INTERNAL:
     * This default constructor must be used in conjunction with the setHelperContext() function.
     * The custom constructor that takes a HelperContext parameter is recommended over this default constructor.
     */
    public SDOEqualityHelper() {
    }

    /**
     * Constructor that takes in a HelperContext instance that contains this equalityHelper.<br>
     * This is the recommended constructor.
     * @param aContext
     */
    public SDOEqualityHelper(HelperContext aContext) {
        aHelperContext = aContext;
    }

    /**
     * <p>Two DataObjects are equalShallow if
     *  they have the same {@link DataObject#getType Type}
     *  and all their compared Properties are equal.
     *  The set of Properties compared are the
     *  {@link DataObject#getInstanceProperties() instance properties}
     *  where property.getType().isDataType() is true
     *  and property.getType() is not ChangeSummaryType.
     * <br>Two of these Property values are equal if they are both not
     *  {@link DataObject#isSet(Property) set}, or set to an equal value
     *  dataObject1.get(property).equals(dataObject2.get(property))
     * <br>If the type is a sequenced type, the sequence entries must be the same.
     *  For each entry x in the sequence where the property is used in the comparison,
     *  dataObject1.getSequence().getValue(x).equals(
     *   dataObject2.getSequence().getValue(x)) and
     *  dataObject1.getSequence().getProperty(x) ==
     *   dataObject2.getSequence().getProperty(x)
     *  must be true.
     * </p>
     *  Returns true the objects have the same Type and all values of all compared Properties are equal.
     * @param dataObject1 DataObject to be compared
     * @param dataObject2 DataObject to be compared
     * @return true the objects have the same Type and all values of all compared Properties are equal.
     */
    @Override
    public boolean equalShallow(DataObject dataObject1, DataObject dataObject2) {
        return compareDataObjects(dataObject1, dataObject2, false);
    }

    /**
     * <p>Two DataObjects are equal(Deep) if they are equalShallow,
     *  all their compared Properties are equal, and all reachable DataObjects in their
     *  graphs excluding containers are equal.
     *  The set of Properties compared are the
     *  {@link DataObject#getInstanceProperties() instance properties}
     *  where property.getType().isDataType() is false,
     *  and is not a container property, ie !property.getOpposite().isContainment()
     * <br>Two of these Property values are equal if they are both not
     *  {@link DataObject#isSet(Property) set}, or all the DataObjects
     *  they refer to are {@link #equal(DataObject, DataObject) equal} in the
     *  context of dataObject1 and dataObject2.
     * <br>Note that properties to a containing DataObject are not compared
     *  which means two DataObject trees can be equal even if their containers are not equal.
     * <br>If the type is a sequenced type, the sequence entries must be the same.
     *  For each entry x in the sequence where the property is used in the comparison,
     *  equal(dataObject1.getSequence().getValue(x),
     *   dataObject2.getSequence().getValue(x)) and
     *  dataObject1.getSequence().getProperty(x) ==  dataObject2.getSequence().getProperty(x)
     *  must be true.
     * </p><p>
     * A DataObject directly or indirectly referenced by dataObject1 or dataObject2
     *  can only be equal to exactly one DataObject directly or indirectly referenced
     *  by dataObject1 or dataObject2, respectively.
     *  This ensures that dataObject1 and dataObject2 are equal if the graph formed by
     *  all their referenced DataObjects have the same shape.
     * </p>
     *  Returns true if the trees of DataObjects are equal(Deep).
     * @param dataObject1 DataObject to be compared
     * @param dataObject2 DataObject to be compared
     * @return true if the trees of DataObjects are equal(Deep).
     */
    @Override
    public boolean equal(DataObject dataObject1, DataObject dataObject2) {
        return compareDataObjects(dataObject1, dataObject2, true);
    }

    /**
     * INTERNAL:
     * Separately, checks the declared properties and open content properties.
     * @param dataObject1   the DataObject to be compared
     * @param dataObject2   the DataObject to be compared
     * @param isDeep          if comparison is deep
     * @return              true if two DataObjects meet requirements of shallow equal or deep equal
     */
    private boolean compareDataObjects(DataObject dataObject1, DataObject dataObject2, boolean isDeep) {
        // Note that properties to a containing DataObject are not compared which
        // means two DataObject trees can be equal even if their containers are not equal.

        if (null == dataObject1) {
            return dataObject2 == null;
        }
        if (null == dataObject2) {// dataObject1 is not null while dataObject2 is null
            return false;
        }

        // they don't have the same type !! assumption is the same for now, but may be changed to use equals  !!
        if (dataObject1.getType() != dataObject2.getType()) {
            return false;
        } else {// type is the same for them

            /**
             * We have 2 strategies here - sequences or dataObjects first?
             * Analysis: A sequence and its dataObject share a subset of element properties.
             * The disjoint set for sequences includes the set of unstructured text settings.
             * The disjoint set for dataObject includes all attribute properties.
             *
             * The choice of which to do first comes down to performance
             */
            /**
             * Compare sequences - only out of order settings and unstructured
             * text will not be picked up by a dataObject comparison.
             * There is no need to check sequenced state on both objects because they share the same SDOType instance.
             */
            if (dataObject1.getType().isSequenced()) {
                if (!compareSequences((SDOSequence) dataObject1.getSequence(), (SDOSequence) dataObject2.getSequence(), isDeep)) {
                    return false;
                }
            }

            // First, compare properties that are not open content.
            // Attribute property differences will not be picked up in the sequence comparison
            if (!compare(dataObject1, dataObject2, isDeep, dataObject1.getType().getProperties())) {
                return false;
            }

            // Second, compare open content properties
            List properties_1 = ((SDODataObject)dataObject1)._getOpenContentProperties();
            List properties_2 = ((SDODataObject)dataObject2)._getOpenContentProperties();

            // different size of open content properties
            if ((properties_1.size() != properties_2.size()) || !properties_1.containsAll(properties_2)) {
                return false;
            }
            if (!compare(dataObject1, dataObject2, isDeep, properties_1)) {
                return false;
            }

            List attrProperties_1 = ((SDODataObject)dataObject1)._getOpenContentPropertiesAttributes();
            List attrProperties_2 = ((SDODataObject)dataObject2)._getOpenContentPropertiesAttributes();

            // different size of open content properties
            if ((attrProperties_1.size() != attrProperties_2.size()) || !attrProperties_1.containsAll(attrProperties_2)) {
                return false;
            }
            if (!compare(dataObject1, dataObject2, isDeep, attrProperties_1)) {
                return false;
            }

            return true;
        }
    }

    /**
     * INTERNAL: Return whether the 2 sequences are equal.
     * Element properties and unstructured text will be compared - attributes are out of scope.
     * <p>
     * For shallow equal - only dataType=true objects are compared, DataObject values are ignored but should be defaults.
     * Note: A setting object should handle its own isEqual() behavior
     *
     * @param aSequence
     * @param aSequenceCopy
     * @param isDeep
     * @return
     */
    private boolean compareSequences(SDOSequence aSequence, SDOSequence aSequenceCopy, boolean isDeep) {
        // corner case: isSequenced set to true after type definition had not sequence
        if ((null == aSequence) && (null == aSequenceCopy)) {
            return true;
        }

        // both sequences must be null
        if ((null == aSequence) || (null == aSequenceCopy)) {
            return false;
        }

        // for shallow equal - match whether we skipped creating settings or set value=null for shallow copies
        if (isDeep && aSequence.size() != aSequenceCopy.size()) {
            return false;
        }
        // the settings inside the sequence must be new objects
        List originalSettingsList = aSequence.getSettings();
        List copySettingsList = aSequenceCopy.getSettings();
        if ((null == originalSettingsList) || (null == copySettingsList)) {
            return false;
        }

        SDOProperty originalProperty = null;
        SDOProperty copyProperty = null;

        /**
         * For shallow equal when dataType is false we do not check this setting,
         * the value will be unset (default value) in the shallow copy.
         * orig                  v1=String  v2=DataObject   v3=String
         * shallowcopy  v1=String  v2=null(default)  v3=String
         * deepcopy       v1=String  v2=DataObject    v3=String
         */
        if (isDeep) {
            for (int index = 0, size = aSequence.size(); index < size; index++) {
                originalProperty = aSequence.getProperty((Setting) originalSettingsList.get(index));
                copyProperty = aSequenceCopy.getProperty((Setting) copySettingsList.get(index));

                // we must handle null properties that represent unstructured text
                // both null = unstructured
                // one null = invalid state (return not equal)
                // both !null = valid state (check equality)
                if (((null == originalProperty) && (null != copyProperty)) || ((null != originalProperty) && (null == copyProperty))) {
                    return false;
                }

                // the property field on the setting must point to the same property instance as the original
                if (!arePropertiesEqual(originalProperty, copyProperty)) {// handle both properties == null
                    return false;
                }

                Object originalValue = aSequence.getValue(index);
                Object copyValue = aSequenceCopy.getValue(index);

                // for unstructuredText (null property) and simple dataTypes we check equality directly
                if ((null == originalProperty) || originalProperty.getType().isDataType()) {
                    // if one of the values is null return false
                    if (((null == originalValue) && (null != copyValue)) || //
                            ((null != originalValue) && (null == copyValue))) {
                        return false;
                    }
                    // if both values are null - they are equal
                    if ((null != originalValue) && !originalValue.equals(copyValue)) {// we can also use !.equals()
                        return false;
                    }
                } else {
                    // For complex types
                    // we do not need to check deep equality on dataObjects twice here, just check instances
                    // because the dataObject compare will iterate all the properties of each dataObject
                    // only compare DataObjects when in a  deep equal
                    if (isDeep) {
                        if ((null != originalValue) && (null != copyValue)) {
                            // setting.isSet is ignored for sequences
                            // perform a deep equal on the single item
                            // the values may not match their types - return false instead of a CCE
                            if (originalValue instanceof DataObject && copyValue instanceof DataObject) {
                                if (!equal((DataObject) originalValue, (DataObject) copyValue)) {
                                    return false;
                                }
                            } else if (originalValue instanceof XMLRoot && copyValue instanceof XMLRoot) {
                                XMLRoot originalXMLRoot = (XMLRoot) originalValue;
                                XMLRoot copyXMLRoot = (XMLRoot) copyValue;
                                // compare local names of XMLRoot objects
                                if (!originalXMLRoot.getLocalName().equals(copyXMLRoot.getLocalName())) {
                                    return false;
                                }
                                // compare uris of XMLRoot objects
                                if (!originalXMLRoot.getNamespaceURI().equals(copyXMLRoot.getNamespaceURI())) {
                                    return false;
                                }

                                Object originalUnwrappedValue = (originalXMLRoot).getObject();
                                Object copyUnwrappedValue = (copyXMLRoot).getObject();
                                if (originalUnwrappedValue instanceof DataObject && copyUnwrappedValue instanceof DataObject) {
                                    if (!equal((DataObject) originalUnwrappedValue, (DataObject) copyUnwrappedValue)) {
                                        return false;
                                    }
                                }
                            } else {
                                return false;
                            }
                        } else {
                            // both values must be null to be equal
                            if (((null == originalValue) && (null != copyValue)) || ((null == copyValue) && (null != originalValue))) {
                                return false;
                            }
                        }
                    } else {
                        // For DataObjects in general anything that is deep equal is also shallow equal - but not the reverse.
                        // In the case of shallow equal on sequences.  We can ignore the state of the 2 complex objects.
                        //   UC1: if aSequenceCopy setting was from a shallowCopy then it will be unset.
                        //   UC2: if aSequenceCopy setting was from a deepCopy or a reversed argument shallowCopy then it may be unset or set.
                        // We will not check for a default value on either sequence setting.
                    }
                }
            }
        } else {
            int cpyIdx = 0;
            boolean locatedSetting;
            // compare settings
            for (int idx = 0; idx < aSequence.getSettings().size(); idx++) {
                SDOProperty nextProperty = aSequence.getProperty(idx);
                if (nextProperty == null || nextProperty.getType().isDataType()) {
                    // compare to the next copy datatype setting
                    Object nextValue = aSequence.getValue(idx);
                    locatedSetting = false;
                    for (; cpyIdx < aSequenceCopy.getSettings().size(); cpyIdx++) {
                        SDOProperty nextCopyProperty = aSequenceCopy.getProperty(cpyIdx);
                        if (nextCopyProperty == null || nextCopyProperty.getType().isDataType()) {
                            // at this point we need to compare the two Settings and their properties
                            Object nextCopyValue = aSequenceCopy.getValue(cpyIdx);
                            if (nextValue == nextCopyValue && arePropertiesEqual(nextProperty, nextCopyProperty)) {
                                locatedSetting = true;
                            }
                            cpyIdx++;
                            break;
                        }
                    }
                    if (!locatedSetting) {
                        return false;
                    }
                }
            }
            // at this point there should not be any more copy settings
            if (getIndexOfNextDataTypeSetting(aSequenceCopy, cpyIdx) != -1) {
                return false;
            }
        }
        return true;
    }

    /**
     * INTERNAL:
     * Convenience method for returning the index of the next DataType
     * Setting in a given sequence.
     *
     * @param aSequence
     * @param index
     * @return the next Setting after index in the sequence, or -1 if none
     */
    private int getIndexOfNextDataTypeSetting(SDOSequence aSequence, int index) {
        List<Setting> settings = aSequence.getSettings();
        for (int i = index; i < settings.size(); i++) {
            SDOProperty nextProperty = aSequence.getProperty(i);
            if (nextProperty == null || nextProperty.getType().isDataType()) {
                return i;
            }
        }
        return -1;
    }

    /**
     * INTERNAL:
     * Convenience method that compares two Property objects for equality
     * @param prop1
     * @param prop2
     * @return
     */
    private boolean arePropertiesEqual(Property prop1, Property prop2) {
        if (((null == prop1) && (null != prop2)) || ((null != prop1) && (null == prop2))) {
            return false;
        }
        // the property field on the setting must point to the same property instance as the original
        if (!prop1.equals(prop2)) {
            return false;
        }
        return true;
    }

    /**
     * INTERNAL:
     * iterativly, compare the values of shared properties in two target DataObjects
     * @param dataObject1   the DataObject to be compared
     * @param dataObject2   the DataObject to be compared
     * @param isDeep          if comparison is deep
     * @param properties     list of properties shared by two DataObjects
     * @return                     true if two DataObjects meet requirements of shallow equal or deep equal
     */
    private boolean compare(DataObject dataObject1, DataObject dataObject2, boolean isDeep, List properties) {
        Iterator iterProperties = properties.iterator();

        while (iterProperties.hasNext()) {
            // !! assumption is two dataobjects share the same property    !!
            SDOProperty p = (SDOProperty)iterProperties.next();
            if (!compareProperty(dataObject1, dataObject2, isDeep, p)) {
                return false;
            }
        }
        return true;
    }

    /**
     * INTERNAL:
     * Recursively [PreOrder sequence] compare corresponding properties of 2 DataObjects
     * check value of property p when p is not a many type property.
     * @param dataObject1   the DataObject to be compared
     * @param dataObject2   the DataObject to be compared
     * @param isDeep          if comparison is deep
     * @param p             the property shared by two DataObjects
     * @return              true if two DataObjects meet requirements of shallow equal or deep equal
     */
    private boolean compareProperty(DataObject dataObject1, DataObject dataObject2, boolean isDeep, SDOProperty p) {
        if (p.isMany()) {
            return compareManyProperty(dataObject1, dataObject2, isDeep, p);
        }

        // base step
        if (p.getType().isDataType() && !p.getType().isChangeSummaryType()) {
            boolean isSet1 = dataObject1.isSet(p);
            boolean isSet2 = dataObject2.isSet(p);
            if (!isSet1 && !isSet2) {
                return true;
            }
            if (isSet1 && isSet2) {
                Object aProperty1 = dataObject1.get(p);
                Object aProperty2 = dataObject2.get(p);

                // if both properties are null then return equality
                if (null == aProperty1) {
                    return aProperty2 == null;
                }
                if (null == aProperty2) {// aProperty1 is not null while aPropertyt2 is null
                    return false;
                }

                return aProperty1.equals(aProperty2);
            }
            return false;
        }

        // recursive step
        if (isDeep && !p.getType().isChangeSummaryType()) {
            if (!dataObject1.isSet(p) && !dataObject2.isSet(p)) {
                return true;
            }

            // #5852525 handle null properties with isSet=true
            if (!p.getType().isDataType()) {
                if (null == p.getOpposite()) {
                    // compare unidirectional or containment=true properties - recursively
                    return compareDataObjects(dataObject1.getDataObject(p), dataObject2.getDataObject(p), isDeep);
                } else {
                    // 20060906: handle bidirectional properties
                    // the check across to another branch in the tree will only go 1 shallow level deep
                    // avoiding an infinite recursive loop and deferring the check for that branch when it
                    // is encountered in its PreOrder sequence.
                    return compareDataObjects(dataObject1.getDataObject(p), dataObject2.getDataObject(p), false);

                    // Spec 3.10 "All reachable DOs in their graphs are equal"
                    // return true since both do1.get(p) and do2.get(p) are set and are instances of DO
                    //return true;
                }
            }
            return false;
        }
        return true;
    }

    /**
     * INTERNAL:
     * iteratively check value of property p when p is many type property.
     * @param dataObject1   the DataObject to be compared
     * @param dataObject2   the DataObject to be compared
     * @param isDeep        if comparison is deep
     * @param p             the property shared by two DataObjects
     * @return              true if two DataObjects meet requirements of shallow equal or deep equal
     */
    private boolean compareManyProperty(DataObject dataObject1, DataObject dataObject2, boolean isDeep, Property p) {
        List l1 = dataObject1.getList(p);
        List l2 = dataObject2.getList(p);

        if (((SDOType)p.getType()).isDataType()) {
            if (dataObject1.isSet(p) != dataObject2.isSet(p)) {
                return false;
            }
            if (l1.size() != l2.size()) {
                return false;
            }
            for (int i = 0; i < l1.size(); i++) {
                Object o1 = l1.get(i);
                Object o2 = l2.get(i);
                if (!o1.equals(o2)) {
                    return false;
                }
            }
            return true;
        }
        if (isDeep) {
            if (dataObject1.isSet(p) != dataObject2.isSet(p)) {
                return false;
            }
            if (l1.size() != l2.size()) {
                return false;
            }

            // !! can a list contains duplicated objects: {A, A'} and A equals A' or {A, A}
            for (int i = 0, size = l1.size(); i < size; i++) {
                DataObject o1_l1 = (DataObject)l1.get(i);
                DataObject o2_l2 = (DataObject)l2.get(i);
                if (!isADataObjectInList(o1_l1, l2)) {
                    return false;
                }
                if (!isADataObjectInList(o2_l2, l1)) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * INTERNAL:
     * @param dataObject1
     * @param objects
     * @return
     */
    private boolean isADataObjectInList(DataObject dataObject1, List objects) {
        Iterator iterObjects = objects.iterator();
        while (iterObjects.hasNext()) {
            DataObject dataObject2 = (DataObject)iterObjects.next();
            if (compareDataObjects(dataObject1, dataObject2, true)) {
                return true;
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * Return the helperContext containing this equalityHelper.
     * @return
     */
    public HelperContext getHelperContext() {
        if(null == aHelperContext) {
            aHelperContext = HelperProvider.getDefaultContext();
        }
        return aHelperContext;
    }

    /**
     * INTERNAL:
     * Set the helperContext if this equalityHelper was created using the default constructor.
     * @param helperContext
     */
    public void setHelperContext(HelperContext helperContext) {
        aHelperContext = helperContext;
    }
}
