/*
 * 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
//     14/05/2012-2.4 Guy Pelletier
//       - 376603: Provide for table per tenant support for multitenant applications
package org.eclipse.persistence.eis;

import java.util.List;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.DescriptorQueryManager;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.eis.mappings.EISCompositeCollectionMapping;
import org.eclipse.persistence.eis.mappings.EISCompositeDirectCollectionMapping;
import org.eclipse.persistence.eis.mappings.EISCompositeObjectMapping;
import org.eclipse.persistence.eis.mappings.EISDirectMapping;
import org.eclipse.persistence.eis.mappings.EISOneToManyMapping;
import org.eclipse.persistence.eis.mappings.EISOneToOneMapping;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.databaseaccess.DatasourceCall;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.expressions.SQLStatement;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.oxm.QNameInheritancePolicy;
import org.eclipse.persistence.internal.oxm.XMLObjectBuilder;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.queries.DatabaseQuery;

/**
 *
 * <p>An <code>EISDescriptor</code> defines the mapping from a JCA data
 * structure to a Java object.  There are two types of EIS descriptors:
 * <ul>
 * <li>Root - indicates to the EclipseLink runtime that the EIS descriptor's
 * reference class is a parent class: no other class will reference it by way of
 * a composite object mapping or composite collection mapping.  For an EIS root
 * descriptor, EIS interactions can be defined to invoke methods on an EIS
 * <li>Composite - indicates to the EclipseLink runtime that the EIS descriptor's
 * reference class may be referenced by a composite object mapping or composite
 * collection mapping
 * </ul>
 *
 * @see org.eclipse.persistence.eis.interactions.EISInteraction
 * @see org.eclipse.persistence.eis.mappings.EISMapping
 *
 * @author James
 * @since OracleAS TopLink 10<i>g</i> (10.0.3)
 */
public class EISDescriptor extends ClassDescriptor {

    /** Define the type of data the descriptor maps to. */
    protected String dataFormat;

    /** Define the valid data formats that the descriptor can map to. */
    public static final String MAPPED = "mapped";
    public static final String INDEXED = "indexed";
    public static final String XML = "xml";

    /** Allow namespaces to be specified for XML type descriptors. */
    protected NamespaceResolver namespaceResolver;

    /**
     * Default constructor.
     */
    public EISDescriptor() {
        super();
        this.shouldOrderMappings = false;
        this.dataFormat = XML;
    }

    @Override
    protected void validateMappingType(DatabaseMapping mapping) {
        if (!(mapping.isEISMapping())) {
            throw DescriptorException.invalidMappingType(mapping);
        }
    }

    /**
     * PUBLIC:
     * Specify the data type name for the class of objects the descriptor maps.
     * This may be the XML schema complex type name, or the JCA record name for the type being mapped.
     */
    public void setDataTypeName(String dataTypeName) throws DescriptorException {
        this.setTableName(dataTypeName);
    }

    /**
     * PUBLIC:
     * Return the XML namespace resolver.
     * XML type EIS descriptor can use a namespace resolver to support XML schema namespaces.
     */
    public NamespaceResolver getNamespaceResolver() {
        return namespaceResolver;
    }

    /**
     * PUBLIC:
     * The inheritance policy is used to define how a descriptor takes part in inheritance.
     * All inheritance properties for both child and parent classes is configured in inheritance policy.
     * Caution must be used in using this method as it lazy initializes an inheritance policy.
     * Calling this on a descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.
     */
    @Override
    public InheritancePolicy getInheritancePolicy() {
        if (inheritancePolicy == null) {
            if(isXMLFormat()) {
                // Lazy initialize to conserve space in non-inherited classes.
                setInheritancePolicy(new org.eclipse.persistence.internal.oxm.QNameInheritancePolicy(this));
            } else {
                setInheritancePolicy(new InheritancePolicy(this));
            }
        }
        return inheritancePolicy;
    }

    /**
     * PUBLIC:
     * Set the XML namespace resolver.
     * XML type EIS descriptor can use a namespace resolver to support XML schema namespaces.
     */
    public void setNamespaceResolver(NamespaceResolver namespaceResolver) {
        this.namespaceResolver = namespaceResolver;
    }

    /**
     * INTERNAL:
     * Avoid SDK initialization.
     */
    @Override
    public void setQueryManager(DescriptorQueryManager queryManager) {
        this.queryManager = queryManager;
        if (queryManager != null) {
            queryManager.setDescriptor(this);
        }
    }

    /**
     * INTERNAL:
     * Configure the object builder for the correct dataFormat.
     */
    @Override
    public void preInitialize(AbstractSession session) {
        // Must not initialize if already done.
        if (isInitialized(PREINITIALIZED)) {
            return;
        }

        if (isXMLFormat()) {
            setObjectBuilder(new XMLObjectBuilder(this));
            if(this.hasInheritance()) {
                ((QNameInheritancePolicy)getInheritancePolicy()).setNamespaceResolver(this.namespaceResolver);
            }
        }

        //        initializeQueryManager();
        super.preInitialize(session);
    }

    /**
     * INTERNAL:
     * Initialize the query manager specific to the descriptor type.
     * Allow the platform to initialize the CRUD queries to defaults.
     */
    @Override
    public void initialize(DescriptorQueryManager queryManager, AbstractSession session) {
        ((DatasourcePlatform)session.getDatasourcePlatform()).initializeDefaultQueries(queryManager, session);
        super.initialize(queryManager, session);
    }

    public boolean isXMLFormat() {
        return this.dataFormat.equals(XML);
    }

    public boolean isMappedFormat() {
        return this.dataFormat.equals(MAPPED);
    }

    public boolean isIndexedFormat() {
        return this.dataFormat.equals(INDEXED);
    }

    /**
     * PUBLIC:
     * Return the data format that the descriptor maps to.
     */
    public String getDataFormat() {
        return dataFormat;
    }

    /**
     * PUBLIC:
     * Specify the data type name for the class of objects the descriptor maps.
     * This may be the XML schema complex type name, or the JCA record name for the type being mapped.
     */
    public String getDataTypeName() throws DescriptorException {
        return this.getTableName();
    }

    /**
     * PUBLIC:
     * Configure the data format that the descriptor maps to.
     */
    public void setDataFormat(String dataFormat) {
        this.dataFormat = dataFormat;
    }

    /**
     * PUBLIC:
     * Configure the data format to use mapped records.
     */
    public void useMappedRecordFormat() {
        setDataFormat(MAPPED);
    }

    /**
     * PUBLIC:
     * Configure the data format to use indexed records.
     */
    public void useIndexedRecordFormat() {
        setDataFormat(INDEXED);
    }

    /**
     * PUBLIC:
     * Configure the data format to use xml records.
     */
    public void useXMLRecordFormat() {
        setDataFormat(XML);
    }

    /**
     * INTERNAL:
     * Build the nested row.
     */
    @Override
    public AbstractRecord buildNestedRowFromFieldValue(Object fieldValue) {
        if (fieldValue instanceof AbstractRecord) {
            return (AbstractRecord)fieldValue;
        }

        // BUG#2667762 if the tag was empty this could be a string of whitespace.
        if (!(fieldValue instanceof List)) {
            return getObjectBuilder().createRecord(0, null);
        }
        List<?> nestedRows = (List<?>)fieldValue;
        if (nestedRows.isEmpty()) {
            return getObjectBuilder().createRecord(0, null);
        } else {
            // BUG#2667762 if the tag was empty this could be a string of whitespace.
            if (!(nestedRows.get(0) instanceof AbstractRecord)) {
                return getObjectBuilder().createRecord(0, null);
            }
            return (AbstractRecord)nestedRows.get(0);
        }
    }

    /**
     * INTERNAL:
     * Build the nested rows.
     */
    @Override
    public Vector buildNestedRowsFromFieldValue(Object fieldValue, AbstractSession session) {
        if (!isXMLFormat()) {
            if (!(fieldValue instanceof List)) {
                return new Vector<>();
            }
            return new Vector<>((List<?>)fieldValue);
        }

        // BUG#2667762 if the tag was empty this could be a string of whitespace.
        if (!(fieldValue instanceof Vector)) {
            return new Vector<>(0);
        }
        return (Vector)fieldValue;
    }

    /**
     * INTERNAL:
     * Extract the direct values from the specified field value.
     * Return them in a vector.
     * The field value could be a vector or could be a text value if only a single value.
     */
    @Override
    public Vector buildDirectValuesFromFieldValue(Object fieldValue) {
        if (!(fieldValue instanceof Vector)) {
            Vector<Object> fieldValues = new Vector<>(1);
            fieldValues.add(fieldValue);
            return fieldValues;
        }
        return (Vector)fieldValue;
    }

    /**
     * INTERNAL:
     * Build the appropriate field value for the specified
     * set of direct values.
     * The database better be expecting a Vector.
     */
    @Override
    public Object buildFieldValueFromDirectValues(Vector directValues, String elementDataTypeName, AbstractSession session) {
        return directValues;
    }

    /**
     * INTERNAL:
     * Build and return the field value from the specified nested database row.
     */
    @Override
    public Object buildFieldValueFromNestedRow(AbstractRecord nestedRow, AbstractSession session) throws DatabaseException {
        Vector<AbstractRecord> nestedRows = new Vector<>(1);
        nestedRows.add(nestedRow);
        return this.buildFieldValueFromNestedRows(nestedRows, "", session);
    }

    /**
     * INTERNAL:
     * Build and return the appropriate field value for the specified
     * set of nested rows.
     */
    @Override
    public Object buildFieldValueFromNestedRows(Vector nestedRows, String structureName, AbstractSession session) throws DatabaseException {
        return nestedRows;
    }

    /**
    * INTERNAL:
    * XML type descriptors should use XMLFields.
    */
    @Override
    public DatabaseField buildField(String fieldName) {
        if (isXMLFormat()) {
            XMLField xmlField = new XMLField(fieldName);
            xmlField.setNamespaceResolver(this.getNamespaceResolver());
            xmlField.initialize();
            return xmlField;
        } else {
            return super.buildField(fieldName);
        }
    }

    /**
     * INTERNAL:
     * If the field is an XMLField then set the namespace resolver from the descriptor.
     * This allows the resolver to only be set in the descriptor.
     */
    @Override
    public DatabaseField buildField(DatabaseField field) {
        if (isXMLFormat()) {
            if(!(field instanceof XMLField)) {
                String xPath = field.getName();
                // Moxy requires /text on elements.
                if ((xPath.indexOf('@') == -1) && (xPath.indexOf("/text()") == -1)) {
                    xPath = xPath + "/text()";
                }
                field = new XMLField(xPath);
            }
            ((XMLField)field).setNamespaceResolver(getNamespaceResolver());
            ((XMLField)field).initialize();
        }
        return super.buildField(field);
    }

    /**
     * Return a new direct/basic mapping for this type of descriptor.
     */
    @Override
    public AbstractDirectMapping newDirectMapping() {
        return new EISDirectMapping();
    }

    /**
     * Return a new aggregate/embedded mapping for this type of descriptor.
     */
    @Override
    public AggregateMapping newAggregateMapping() {
        return new EISCompositeObjectMapping();
    }

    /**
     * Return a new aggregate collection/element collection mapping for this type of descriptor.
     */
    @Override
    public DatabaseMapping newAggregateCollectionMapping() {
        return new EISCompositeCollectionMapping();
    }

    /**
     * Return a new direct collection/element collection mapping for this type of descriptor.
     */
    @Override
    public DatabaseMapping newDirectCollectionMapping() {
        return new EISCompositeDirectCollectionMapping();
    }

    /**
     * Return a new one to one mapping for this type of descriptor.
     */
    @Override
    public ObjectReferenceMapping newOneToOneMapping() {
        return new EISOneToOneMapping();
    }

    /**
     * Return a new many to one mapping for this type of descriptor.
     */
    @Override
    public ObjectReferenceMapping newManyToOneMapping() {
        return new EISOneToOneMapping();
    }

    /**
     * Return a new one to many mapping for this type of descriptor.
     */
    @Override
    public CollectionMapping newOneToManyMapping() {
        return new EISOneToManyMapping();
    }

    /**
     * Return a new one to many mapping for this type of descriptor.
     */
    @Override
    public CollectionMapping newUnidirectionalOneToManyMapping() {
        return new EISOneToManyMapping();
    }

    /**
     * Return a new one to many mapping for this type of descriptor.
     */
    @Override
    public CollectionMapping newManyToManyMapping() {
        return new EISOneToManyMapping();
    }

    /**
     * PUBLIC: Add a direct mapping to the receiver. The new mapping specifies
     * that an instance variable of the class of objects which the receiver
     * describes maps in the default manner for its type to the indicated
     * database field.
     *
     * @param attributeName
     *            instanceVariableName is the name of an instance variable of
     *            the class which the receiver describes.
     * @param fieldName
     *            fieldName is the name of the xml element or attribute which
     *            corresponds with the designated instance variable.
     * @return The newly created DatabaseMapping is returned.
     */
    @Override
    public DatabaseMapping addDirectMapping(String attributeName, String fieldName) {
        EISDirectMapping mapping = new EISDirectMapping();
        mapping.setAttributeName(attributeName);

        if (isXMLFormat()) {
            mapping.setXPath(fieldName);
        } else {
            mapping.setFieldName(fieldName);
        }

        return addMapping(mapping);
    }

    /**
     * PUBLIC:
     * Add a direct to node mapping to the receiver. The new mapping specifies that
     * a variable accessed by the get and set methods of the class of objects which
     * the receiver describes maps in  the default manner for its type to the indicated
     * database field.
     */
    @Override
    public DatabaseMapping addDirectMapping(String attributeName, String getMethodName, String setMethodName, String fieldName) {
        EISDirectMapping mapping = new EISDirectMapping();

        mapping.setAttributeName(attributeName);
        mapping.setSetMethodName(setMethodName);
        mapping.setGetMethodName(getMethodName);
        if (isXMLFormat()) {
            mapping.setXPath(fieldName);
        } else {
            mapping.setFieldName(fieldName);
        }
        return addMapping(mapping);
    }

    /**
     * PUBLIC:
     * Specify the primary key field.
     * This should be called for each field that make up the primary key.
     * For EIS XML Descriptors use the addPrimaryKeyField(DatabaseField) API
     * and supply an org.eclipse.persistence.oxm.XMLField parameter instead of using this method
     */
    @Override
    public void addPrimaryKeyFieldName(String fieldName) {
        if (isXMLFormat()) {
            addPrimaryKeyField(new XMLField(fieldName));
        } else {
            super.addPrimaryKeyFieldName(fieldName);
        }
    }

    /**
     * PUBLIC:
     * Set the sequence number field name.
     * This is the field in the descriptors table that needs its value to be generated.
     * This is normally the primary key field of the descriptor.
     * For EIS XML Descriptors use the setSequenceNumberFieldName(DatabaseField) API
     * and supply an org.eclipse.persistence.oxm.XMLField parameter instead of using this method
     */
    @Override
    public void setSequenceNumberFieldName(String fieldName) {
        super.setSequenceNumberFieldName(fieldName);
    }

    /**
     * INTERNAL:
     * Override this method to throw an exception. SQL should not be generated for
     * EIS Calls.
     */
    @Override
    public DatasourceCall buildCallFromStatement(SQLStatement statement, DatabaseQuery query, AbstractSession session) {
        return ((EISPlatform)session.getDatasourcePlatform()).buildCallFromStatement(statement, query, session);
    }

    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        if (isXMLFormat()) {
            for(int x = 0, primaryKeyFieldsSize = this.primaryKeyFields.size(); x<primaryKeyFieldsSize; x++) {
                XMLField pkField = (XMLField) this.primaryKeyFields.get(x);
                pkField.setNamespaceResolver(this.namespaceResolver);
                pkField.initialize();
            }
        }
        super.initialize(session);
    }

    /**
     * INTERNAL: This is needed by regular aggregate descriptors * but not by
     * EIS aggregate descriptors.
     */
    @Override
    public void initializeAggregateInheritancePolicy(AbstractSession session) {
        // do nothing, since the parent descriptor was already modified during pre-initialize
    }

    /**
     * INTERNAL:
     * XML descriptors are initialized normally, since they do
     * not need to be cloned by ESI aggregate mappings.
     */
    @Override
    public boolean requiresInitialization(AbstractSession session) {
        return (!isDescriptorForInterface());
    }

    /**
     * Aggregates use a dummy table as default.
     */
    @Override
    protected DatabaseTable extractDefaultTable() {
        if (this.isAggregateDescriptor()) {
            return new DatabaseTable();
        }
        return super.extractDefaultTable();
    }

    /**
     * INTERNAL:
     * Indicates if a return type is required for the field set on the
     * returning policy.  For EIS descriptors, this should always
     * return false.
     */
    @Override
    public boolean isReturnTypeRequiredForReturningPolicy() {
        return false;
    }

    /**
     * PUBLIC:
     * Return if the descriptor maps to an EIS or NoSQL datasource.
     */
    @Override
    public boolean isEISDescriptor() {
        return true;
    }

    /**
     * INTERNAL:
     * Return if change sets are required for new objects.
     */
    @Override
    public boolean shouldUseFullChangeSetsForNewObjects() {
        // This is currently set to allow EIS tests to pass the same as before.
        // TODO: It should be removed, and the test issues fixed (bug was logged).
        return true;
    }
}
