/*
 * 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
//     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 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 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;
    }
}
