/*
 * Copyright (c) 1998, 2021 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.
     */
    protected 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<DatabaseField> buildAllNonPrimaryKeyFields() {
        List<DatabaseField> 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 <T> T 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 <T> T 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 <T> T 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<Map<DatabaseField, DatabaseField>> enumtr = descriptor.getAdditionalTablePrimaryKeyFields().values().iterator();
                         enumtr.hasNext();) {
                    if (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<DatabaseField> 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();
        }
    }
}
