/*
 * 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.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.emptyList();
        }
        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 = new ArrayList<>();
                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;
    }
}
