/*
 * 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
//     05/16/2008-1.0M8 Guy Pelletier
//       - 218084: Implement metadata merging functionality between mapping files
//     04/27/2010-2.1 Guy Pelletier
//       - 309856: MappedSuperclasses from XML are not being initialized properly
//     03/24/2011-2.3 Guy Pelletier
//       - 337323: Multi-tenant with shared schema support (part 1)
//     11/19/2012-2.5 Guy Pelletier
//       - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
package org.eclipse.persistence.internal.jpa.metadata.locking;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.persistence.annotations.OptimisticLockingType;
import org.eclipse.persistence.descriptors.AllFieldsLockingPolicy;
import org.eclipse.persistence.descriptors.ChangedFieldsLockingPolicy;
import org.eclipse.persistence.descriptors.SelectedFieldsLockingPolicy;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor;
import org.eclipse.persistence.internal.jpa.metadata.ORMetadata;
import org.eclipse.persistence.internal.jpa.metadata.accessors.MetadataAccessor;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAnnotation;
import org.eclipse.persistence.internal.jpa.metadata.columns.ColumnMetadata;

/**
 * Object to hold onto optimistic locking metadata.
 *
 * Key notes:
 * - any metadata mapped from XML to this class must be compared in the
 *   equals method.
 * - when loading from annotations, the constructor accepts the metadata
 *   accessor this metadata was loaded from. Used it to look up any
 *   'companion' annotation needed for processing.
 * - methods should be preserved in alphabetical order.
 *
 * @author Guy Pelletier
 * @since TopLink 11g
 */
public class OptimisticLockingMetadata extends ORMetadata {
    private Boolean m_cascade;
    private List<ColumnMetadata> m_selectedColumns = new ArrayList<ColumnMetadata>();
    private String m_type;

    /**
     * INTERNAL:
     * Used for XML loading.
     */
    public OptimisticLockingMetadata() {
        super("<optimistic-locking>");
    }

    /**
     * INTERNAL:
     * Used for annotation loading.
     */
    public OptimisticLockingMetadata(MetadataAnnotation optimisticLocking, MetadataAccessor accessor) {
        super(optimisticLocking, accessor);

        m_type = optimisticLocking.getAttributeString("type");
        m_cascade = optimisticLocking.getAttributeBooleanDefaultFalse("cascade");

        for (Object selectedColumn : optimisticLocking.getAttributeArray("selectedColumns")) {
            m_selectedColumns.add(new ColumnMetadata((MetadataAnnotation)selectedColumn, accessor));
        }
    }

    /**
     * INTERNAL:
     */
    @Override
    public boolean equals(Object objectToCompare) {
        if (objectToCompare instanceof OptimisticLockingMetadata) {
            OptimisticLockingMetadata optimisticLocking = (OptimisticLockingMetadata) objectToCompare;

            if (! valuesMatch(m_cascade, optimisticLocking.getCascade())) {
                return false;
            }

            if (! valuesMatch(m_selectedColumns, optimisticLocking.getSelectedColumns())) {
                return false;
            }

            return valuesMatch(m_type, optimisticLocking.getType());
        }

        return false;
    }

    @Override
    public int hashCode() {
        int result = m_cascade != null ? m_cascade.hashCode() : 0;
        result = 31 * result + (m_selectedColumns != null ? m_selectedColumns.hashCode() : 0);
        result = 31 * result + (m_type != null ? m_type.hashCode() : 0);
        return result;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public Boolean getCascade() {
        return m_cascade;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public List<ColumnMetadata> getSelectedColumns() {
        return m_selectedColumns;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public String getType() {
        return m_type;
    }

    /**
     * INTERNAL:
     */
    public boolean hasSelectedColumns() {
        return ! m_selectedColumns.isEmpty();
    }

    /**
     * INTERNAL:
     */
    public void process(MetadataDescriptor descriptor) {
        // Process the type. A null will default to VERSION_COLUMN.
        if (m_type == null || m_type.equals(OptimisticLockingType.VERSION_COLUMN.name())) {
            // A version annotation or element should be define and discovered
            // in later processing.
            descriptor.setUsesCascadedOptimisticLocking(m_cascade != null && m_cascade);
        } else if (m_type.equals(OptimisticLockingType.ALL_COLUMNS.name())) {
            descriptor.setOptimisticLockingPolicy(new AllFieldsLockingPolicy());
        } else if (m_type.equals(OptimisticLockingType.CHANGED_COLUMNS.name())) {
            descriptor.setOptimisticLockingPolicy(new ChangedFieldsLockingPolicy());
        } else if (m_type.equals(OptimisticLockingType.SELECTED_COLUMNS.name())) {
            if (m_selectedColumns.isEmpty()) {
                throw ValidationException.optimisticLockingSelectedColumnNamesNotSpecified(descriptor.getJavaClass());
            } else {
                SelectedFieldsLockingPolicy policy = new SelectedFieldsLockingPolicy();

                // Process the selectedColumns
                for (ColumnMetadata selectedColumn : m_selectedColumns) {
                    if (selectedColumn.getName().equals("")) {
                        throw ValidationException.optimisticLockingSelectedColumnNamesNotSpecified(descriptor.getJavaClass());
                    } else {
                        policy.addLockFieldName(selectedColumn.getName());
                    }
                }

                descriptor.setOptimisticLockingPolicy(policy);
            }
        }
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setCascade(Boolean cascade) {
        m_cascade = cascade;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setSelectedColumns(List<ColumnMetadata> selectedColumns) {
        m_selectedColumns = selectedColumns;
    }

    /**
     * INTERNAL:
     * Used for OX mapping.
     */
    public void setType(String type) {
        m_type = type;
    }
}
