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

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DatabaseMapping.WriteType;
import org.eclipse.persistence.queries.ObjectLevelModifyQuery;

/**
 * <p>
 * <b>Purpose</b>: An implementation of the OptimisticLockingPolicy interface.
 * This policy compares selected fields in the WHERE clause when doing an update
 * or a delete. If any field has been changed, an optimistic locking exception
 * will be thrown. Note that the fields specified must be mapped and not be
 * primary keys.
 * <p>
 * NOTE: This policy can only be used inside a unit of work.
 *
 * @since TopLink 2.5
 */
public class SelectedFieldsLockingPolicy extends FieldsLockingPolicy {
    protected Map<DatabaseTable, List<DatabaseField>> lockFieldsByTable;
    protected List<DatabaseField> lockFields;

    /**
     * PUBLIC: Create a new selected fields locking policy. A field locking
     * policy is based on locking on the specified 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 SelectedFieldsLockingPolicy() {
        super();
        this.lockFieldsByTable = new HashMap(4);
        this.lockFields = new ArrayList();
    }

    /**
     * PUBLIC: Add a field name to lock on. All fields in this list will be
     * compared when updating if the value of any of the fields does not match
     * the value in memory, an OptimisticLockException will be thrown.
     *
     * Note: An Automatic update will not be done on this field, only a
     * comparison occurs.
     */
    public void addLockFieldName(String fieldName) {
        getLockFields().add(new DatabaseField(fieldName));
    }

    /**
     * INTERNAL: Values to be included in the locking mechanism are added to the
     * translation row. For changed fields the normal build row is ok as only
     * changed fields matter.
     */
    @Override
    public void addLockValuesToTranslationRow(ObjectLevelModifyQuery query) throws DatabaseException {
        Object object;
        verifyUsage(query.getSession());
        if (query.isDeleteObjectQuery()) {
            object = query.getObject();
        } else {
            object = query.getBackupClone();
        }

        // EL bug 319759
        if (query.isUpdateObjectQuery()) {
            query.setShouldValidateUpdateCallCacheUse(true);
        }

        for (Iterator<List<DatabaseField>> fields = getLockFieldsByTable().values().iterator(); fields.hasNext();) {
            for (DatabaseField field : fields.next()) {
                DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForField(field);
                // Bug5892889, Exception will be thrown if no matched database
                // field found
                if (mapping == null) {
                    throw DatabaseException.specifiedLockingFieldsNotFoundInDatabase(field.getQualifiedName());
                } else {
                    mapping.writeFromObjectIntoRow(object, query.getTranslationRow(), query.getSession(), WriteType.UNDEFINED);
                }
            }
        }
    }

    /**
     * INTERNAL: returns the lock fields to compare based on the passed in
     * table.
     */
    @Override
    protected List<DatabaseField> getFieldsToCompare(org.eclipse.persistence.internal.helper.DatabaseTable table, AbstractRecord transRow, AbstractRecord modifyRow) {
        return getLockFields(table);
    }

    /**
     * INTERNAL: Returns the lock fields
     */
    public List<DatabaseField> getLockFields() {
        return lockFields;
    }

    /**
     * INTERNAL: returns the lock fields based on the passed in table
     */
    protected List<DatabaseField> getLockFields(DatabaseTable table) {
        List<DatabaseField> temp = this.lockFieldsByTable.get(table);
        if (temp == null) {
            return Collections.EMPTY_LIST;
        }
        return temp;
    }

    /**
     * INTERNAL: returns the lock fields
     */
    protected Map<DatabaseTable, List<DatabaseField>> getLockFieldsByTable() {
        return lockFieldsByTable;
    }

    /**
     * INTERNAL: It is responsible for initializing the policy;
     */
    @Override
    public void initialize(AbstractSession session) {
        super.initialize(session);
        List<DatabaseField> lockFields = getLockFields();
        int size = lockFields.size();
        for (int index = 0; index < size; index++) {
            DatabaseField field = lockFields.get(index);
            field = descriptor.buildField(field);
            lockFields.set(index, field);
            List<DatabaseField> fieldsForTable = getLockFieldsByTable().get(field.getTable());
            if (fieldsForTable == null) {
                fieldsForTable = org.eclipse.persistence.internal.helper.NonSynchronizedVector.newInstance();
                getLockFieldsByTable().put(field.getTable(), fieldsForTable);
            }
            fieldsForTable.add(field);
        }
    }

    /**
     * PUBLIC: Set the field names to lock on. All fields in this list will be
     * compared when Updating. If the value of any of the fields does not match
     * the value in memory, an OptimisticLockException will be thrown.
     *
     * Note: An Automatic update will not be done on this field, only a
     * comparison occurs.
     */
    public void setLockFieldNames(List<String> lockFieldNames) {
        for (String name : lockFieldNames) {
            addLockFieldName(name);
        }
    }

    /**
     * INTERNAL: Sets the lock fields
     */
    protected void setLockFields(List<DatabaseField> lockFields) {
        this.lockFields = lockFields;
    }

    /**
     * INTERNAL: Used to set the field names to be used in this policy.
     */
    protected void setLockFieldsByTable(Map<DatabaseTable, List<DatabaseField>> lockFieldsByTable) {
        this.lockFieldsByTable = lockFieldsByTable;
    }
}
