/*
 * Copyright (c) 1998, 2019 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.descriptors;

import java.util.*;
import org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.exceptions.*;

/**
 * <p><b>Purpose</b>: An abstract superclass of some implementations of the OptimisticLockingPolicy
 * interface.  All of the subclasses of this class implement OptimisticLocking
 * based on mapped fields in the object.  These fields are only compared and not modified.
 * Any modification (incrementing etc..) must be handled by the application.
 *
 * @see AllFieldsLockingPolicy
 * @see ChangedFieldsLockingPolicy
 * @see SelectedFieldsLockingPolicy
 * @since TopLink 2.1
 * @author Peter Krogh
 */
public abstract class FieldsLockingPolicy implements OptimisticLockingPolicy {
    protected ClassDescriptor descriptor;
    protected List<DatabaseField> allNonPrimaryKeyFields;

    /**
     * PUBLIC:
     * Create a new field locking policy.
     * A field locking policy is based on locking on a subset of fields by comparing with their previous values to detect field-level collisions.
     * Note: the unit of work must be used for all updates when using field locking.
     */
    public FieldsLockingPolicy() {
        super();
    }

    /**
     * INTERNAL:
     * Add update fields for template row.
     * These are any unmapped fields required to write in an update.
     * Since all fields are mapped, there is nothing required.
     */
    @Override
    public void addLockFieldsToUpdateRow(AbstractRecord Record, AbstractSession session) {
        // Nothing required.
    }

    /**
     * INTERNAL:
     * Values to be included in the locking mechanism are added
     * to the translation row.  Set the translation row to all the original field values.
     */
    @Override
    public abstract void addLockValuesToTranslationRow(ObjectLevelModifyQuery query);

    /**
     * INTERNAL:
     * Returns the fields that should be compared in the where clause.
     * In this case, it is all the fields, except for the primary key
     * and class indicator fields.
     * This is called during lazy initialization.
     */
    protected List buildAllNonPrimaryKeyFields() {
        List fields = new ArrayList();
        for (DatabaseField dbField : descriptor.getSelectionFields()) {
            if (!isPrimaryKey(dbField)) {
                if (descriptor.hasInheritance()) {
                    DatabaseField classField = descriptor.getInheritancePolicy().getClassIndicatorField();
                    if (!((classField == null) || dbField.equals(classField))) {
                        fields.add(dbField);
                    }
                } else {
                    fields.add(dbField);
                }
            }
        }

        /* CR#... nullpoint occurs if null is returned, not sure why this was here.
        if (fields.isEmpty()) {
            return null;
        }*/
        return fields;
    }

    /**
     * INTERNAL:
     * When given an expression, this method will return a new expression with the optimistic
     * locking values included.  The values are taken from the passed in database row.
     * This expression will be used in a delete call.
     */
    @Override
    public Expression buildDeleteExpression(DatabaseTable table, Expression mainExpression, AbstractRecord row) {
        return mainExpression.and(buildExpression(table, row, null, mainExpression.getBuilder()));
    }

    /**
     * INTERNAL:
     * returns the expression to be used in both the delete and update where clause.
     */
    protected Expression buildExpression(DatabaseTable table, AbstractRecord transRow, AbstractRecord modifyRow, ExpressionBuilder builder) {
        Expression exp = null;
        DatabaseField field;
        Iterator<DatabaseField> iterator = getFieldsToCompare(table, transRow, modifyRow).iterator();
        if (iterator.hasNext()) {
            field = iterator.next();//First element
            exp = builder.getField(field).equal(builder.getParameter(field));
        }
        while (iterator.hasNext()) {
            field = iterator.next();
            exp = exp.and(builder.getField(field).equal(builder.getParameter(field)));
        }
        return exp;
    }

    /**
     * INTERNAL:
     * This method must be included in any locking policy.  When given an
     * expression, this method will return a new expression with the optimistic
     * locking values included.  The values are taken from the passed in database row.
     * This expression will be used in a delete call.
     */
    @Override
    public Expression buildUpdateExpression(DatabaseTable table, Expression mainExpression, AbstractRecord transRow, AbstractRecord modifyRow) {
        return mainExpression.and(buildExpression(table, transRow, modifyRow, mainExpression.getBuilder()));
    }

    /**
     * INTERNAL:
     * Clone the policy
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    /**
     * INTERNAL:
     * Indicates whether compareWriteLockValues method is supported by the policy.
     * Numeric or timestamp lock values could be compared:
     * for every pair of values v1 and v2 - either {@literal v1<v2; or v1==v2; or v1>v2}.
     * However it's impossible to compare values for FieldsLockingPolicy for two reasons:
     * 1. there is no "linear order": {@literal v1<v2 and v>v2} is not defined: either v1==v2 or v1!=v2;
     * 2. locking value is not a single field which is not part of mapped object value
     *    but rather a set of object's mapped fields. That means any object's mapped attribute change
     *    is potentially a change of the locking value.
     *    For ChangedFieldsLockingPolicy every mapped attribute's change is a change of locking value.
     *    The pattern used by versioning: "if the original locking value is unchanged
     *    then the object hasn't been changed outside of the application", which allows
     *    to distinguish between the change made inside and outside the application,
     *    doesn't work for fields locking.
     *    It degenerates into useless pattern: "if the original locking value is unchanged
     *    then the object hasn't been changed".
     *
     * Use compareWriteLockValues method only if this method returns true.
     */
    @Override
    public boolean supportsWriteLockValuesComparison() {
        return false;
    }

    /**
     * INTERNAL:
     * This method shouldn't be called if supportsWriteLockValuesComparison() returns false.
     * This method compares two writeLockValues.
     * The writeLockValues should be non-null and of the correct type.
     * Returns:
     * -1 if value1 is less (older) than value2;
     *  0 if value1 equals value2;
     *  1 if value1 is greater (newer) than value2.
     * Throws:
     *  NullPointerException if the passed value is null;
     *  ClassCastException if the passed value is of a wrong type.
     */
    @Override
    public int compareWriteLockValues(Object value1, Object value2){
        // should never be called because supportsWriteLockValuesComparison() returns false.
        return -1;
    }

    /**
     * INTERNAL:
     * Returns the fields that should be compared in the where clause.
     * In this case, it is all the fields, except for the primary key
     * and class indicator field.
     */
    protected List<DatabaseField> getAllNonPrimaryKeyFields() {
        if (allNonPrimaryKeyFields == null) {
            allNonPrimaryKeyFields = buildAllNonPrimaryKeyFields();
        }
        return allNonPrimaryKeyFields;
    }

    /**
     * INTERNAL:
     * filter the fields based on the passed in table.  Only return fields of this table.
     */
    protected List<DatabaseField> getAllNonPrimaryKeyFields(DatabaseTable table) {
        List<DatabaseField> filteredFields = new ArrayList<>();
        for (DatabaseField dbField : getAllNonPrimaryKeyFields()) {
            if (dbField.getTableName().equals(table.getName())) {
                filteredFields.add(dbField);
            }
        }
        return filteredFields;
    }

    /**
     * INTERNAL:
     * This is the base value that is older than all other values, it is used in the place of
     * null in some situations.
     */
    @Override
    public Object getBaseValue(){
        return null; // this locking type does not store values in the cache
    }

    /**
     * INTERNAL:
     * Returns the fields that should be compared in the where clause.
     * This method must be implemented by the subclass
     */
    protected abstract List<DatabaseField> getFieldsToCompare(DatabaseTable table, AbstractRecord transRow, AbstractRecord modifyRow);

    /**
     * INTERNAL:
     * Return the write lock field.
     */
    @Override
    public DatabaseField getWriteLockField() {
        // Does not apply to any field locking policy, so return null
        return null;
    }

    /**
     * INTERNAL:
     */
    @Override
    public Expression getWriteLockUpdateExpression(ExpressionBuilder builder, AbstractSession session) {
        // Does not apply to any field locking policy, so return null
        return null;
    }

    /**
     * ADVANCED:
     * returns the LockOnChange mode for this policy.  This mode specifies if a
     * Optimistic Write lock should be enforced on this entity when a set of mappings are changed.
     * Unfortunately this locking policy can not enforce an optimistic write lock unless a FK or DTF field
     * has changed so this type returns LockOnChange.NONE
     */
    @Override
    public LockOnChange getLockOnChangeMode(){
        return LockOnChange.NONE;
    }

    /**
     * INTERNAL:
     * Return the value that should be stored in the identity map.  If the value
     * is stored in the object, then return a null.
     */
    @Override
    public Object getValueToPutInCache(AbstractRecord row, AbstractSession session) {
        return null;
    }

    /**
     * INTERNAL:
     * Return the number of version difference between the two states of the object.
     */
    @Override
    public int getVersionDifference(Object currentValue, Object domainObject, Object primaryKeys, AbstractSession session) {
        // There is no way of knowing what the difference is so return 0
        // This should never be called for field locking.
        return 0;
    }

    /**
     * INTERNAL:
     * This method will return the optimistic lock value for the object
     */
    @Override
    public Object getWriteLockValue(Object domainObject, Object primaryKey, AbstractSession session) {
        //There is no way of knowing if this value is newer or not, so always return true.
        return null;
    }

    /**
     * INTERNAL:
     * It is responsible for initializing the policy;
     */
    @Override
    public void initialize(AbstractSession session) {
        // If the version field is not in the primary table, then they cannot be batched together.
        if (this.descriptor.getTables().size() > 0) {
            this.descriptor.setHasMultipleTableConstraintDependecy(true);
        }
    }

    /**
     * INTERNAL:
     * It is responsible for initializing the policy;
     */
    @Override
    public void initializeProperties() {
        //nothing to do
    }

     /**
      * PUBLIC:
      * Return true if the lock value is stored in the cache.
      */
     @Override
    public boolean isStoredInCache() {
         return false;
     }

    /**
     * PUBLIC:
     * Return true if the policy uses cascade locking. Currently, not supported
     * on this policy at this time.
     */
     @Override
    public boolean isCascaded() {
         return false;
     }

    /**
     * INTERNAL:
     * Compares the value  and the value from the object
     * (or cache).  Will return true if the object is newer
     * than the row.
     */
    @Override
    public boolean isNewerVersion(Object currentValue, Object domainObject, Object primaryKey, AbstractSession session) {
        //There is no way of knowing if this value is newer or not, so always return true.
        return true;
    }

    /**
     * INTERNAL:
     * Compares the value from the row and from the object
     * (or cache).  Will return true if the object is newer
     * than the row.
     */
    @Override
    public boolean isNewerVersion(AbstractRecord Record, Object domainObject, Object primaryKey, AbstractSession session) {
        //There is no way of knowing if this value is newer or not, so always return true.
        return true;
    }

    /**
     * INTERNAL:
     * Returns whether or not this field is a primary key.
     * This method will also return true for secondary table primarykeys
     */
    protected boolean isPrimaryKey(DatabaseField dbField) {
        if (descriptor.getPrimaryKeyFields().contains(dbField)) {
            return true;
        } else {
            if (descriptor.isMultipleTableDescriptor()) {
                for (Iterator enumtr = descriptor.getAdditionalTablePrimaryKeyFields().values().iterator();
                         enumtr.hasNext();) {
                    if (((Map)enumtr.next()).containsKey(dbField)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * Only applicable when the value is stored in the cache.
     */
    @Override
    public void mergeIntoParentCache(UnitOfWorkImpl uow, Object primaryKey, Object object) {
        // nothing to do
    }

    /**
     * INTERNAL:
     * This method should merge changes from the parent into the child.
     *
     * #see this method in VersionLockingPolicy
     */
    @Override
    public void mergeIntoParentCache(CacheKey unitOfWorkCacheKey, CacheKey parentSessionCacheKey){
        // nothing to do
    }

    /**
     * INTERNAL: Set method for all the primary keys
     */
    protected void setAllNonPrimaryKeyFields(List allNonPrimaryKeyFields) {
        this.allNonPrimaryKeyFields = allNonPrimaryKeyFields;
    }

    /**
     * INTERNAL: Set method for the descriptor
     */
    @Override
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
    }

    /**
     * ADVANCED:
     * Sets the LockOnChange mode for this policy.  This mode specifies if a
     * Optimistic Write lock should be enforced on this entity when set of mappings are changed.
     * Unfortunately this locking policy can not always force an optimistic lock unless the core fields have changed
     */
    @Override
    public void setLockOnChangeMode(LockOnChange lockOnChangeMode){
        //no-op for this type
    }
    /**
     * INTERNAL:
     * Put the initial writelock value into the modifyRow.
     * There is nothing to do because all the lock values are in the mappings.
     */
    @Override
    public void setupWriteFieldsForInsert(ObjectLevelModifyQuery query) {
        //nothing to do.
    }

    /**
     * INTERNAL:
     * Nothing to do because all updates are handled by the application
     */
    @Override
    public void updateRowAndObjectForUpdate(ObjectLevelModifyQuery query, Object domainObject) {
        //nothing to do
    }

    /**
     * INTERNAL:
     * Returns true if the policy has been set to set an optimistic read lock when a owning mapping changes.
     * Unfortunately this locking policy can not always force an optimistic lock unless the core fields have changed
     */
    @Override
    public boolean shouldUpdateVersionOnOwnedMappingChange(){
        return false;
    }

    /**
     * INTERNAL:
     * Returns true if the policy has been set to set an optimistic read lock when any mapping changes.
     * Unfortunately this locking policy can not always force an optimistic lock unless the core fields have changed
     */
    @Override
    public boolean shouldUpdateVersionOnMappingChange(){
        return false;
    }
    /**
     * INTERNAL:
     * Check the row count for lock failure.
     */
    @Override
    public void validateDelete(int rowCount, Object object, DeleteObjectQuery query) {
        if (rowCount <= 0) {
            // Mark the object as invalid in the session cache.
            query.getSession().getParentIdentityMapSession(query, true, true).getIdentityMapAccessor().invalidateObject(object);
            throw OptimisticLockException.objectChangedSinceLastReadWhenDeleting(object, query);
        }
    }

    /**
     * INTERNAL:
     * Check the row count for lock failure.
     */
    @Override
    public void validateUpdate(int rowCount, Object object, WriteObjectQuery query) {
        if (rowCount <= 0) {
            // Mark the object as invalid in the session cache.
            query.getSession().getParentIdentityMapSession(query, true, true).getIdentityMapAccessor().invalidateObject(object);
            throw OptimisticLockException.objectChangedSinceLastReadWhenUpdating(object, query);
        }
    }

    /**
     * INTERNAL:
     * throw an exception if not inside a unit of work at this point
     */
    protected void verifyUsage(AbstractSession session) {
        if (!session.isUnitOfWork()) {
            throw ValidationException.fieldLevelLockingNotSupportedWithoutUnitOfWork();
        }
    }
}
