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

import java.util.*;

import javax.xml.namespace.QName;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.ConversionException;
import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.descriptors.ObjectBuilder;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheId;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.Reference;
import org.eclipse.persistence.internal.oxm.ReferenceResolver;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLUnionField;
import org.eclipse.persistence.oxm.record.DOMRecord;
import org.eclipse.persistence.oxm.record.XMLRecord;
import org.eclipse.persistence.queries.ObjectBuildingQuery;

/**
 * TopLink OXM version of a 1-1 mapping.  A list of source-target key field
 * associations is used to link the source xpaths to their related target xpaths,
 * and hence their primary key (unique identifier) values used when (un)marshalling.
 * This mapping has a Vector of XMLFields as opposed to a single XMLField.
 *
 * It is important to note that each target xpath is assumed to be set as a primary
 * key field on the target (reference) class descriptor - this is necessary in order
 * to locate the correct target object instance in the session cache when resolving
 * mapping references.
 */
public class XMLObjectReferenceMapping extends AggregateMapping implements ObjectReferenceMapping<AbstractSession, AttributeAccessor, ContainerPolicy, ClassDescriptor, DatabaseField, UnmarshalRecord, XMLField, XMLRecord>, XMLMapping {
    protected HashMap sourceToTargetKeyFieldAssociations;
    protected Vector sourceToTargetKeys; // maintain the order of the keys
    private boolean isWriteOnly;
    private XMLInverseReferenceMapping inverseReferenceMapping;

    /**
     * PUBLIC:
     * The default constructor initializes the sourceToTargetKeyFieldAssociations
     * and sourceToTargetKeys data structures.
     */
    public XMLObjectReferenceMapping() {
        sourceToTargetKeyFieldAssociations = new HashMap();
        sourceToTargetKeys = new Vector();
    }

    /**
     * PUBLIC:
     * Add a source-target xpath pair to the map.
     *
     */
    @Override
    public void addSourceToTargetKeyFieldAssociation(String srcXPath, String tgtXPath) {
        XMLField srcFld = new XMLField(srcXPath);
        sourceToTargetKeys.add(srcFld);
        if(null == tgtXPath) {
            sourceToTargetKeyFieldAssociations.put(srcFld, null);
        } else {
            sourceToTargetKeyFieldAssociations.put(srcFld, new XMLField(tgtXPath));
        }
    }

    public void addSourceToTargetKeyFieldAssociation(XMLField srcField, XMLField tgtField) {
        sourceToTargetKeys.add(srcField);
        sourceToTargetKeyFieldAssociations.put(srcField, tgtField);
    }

    /**
     * INTERNAL:
     * Retrieve the target object's primary key value that is mapped to a given
     * source xpath (in the source-target key field association list).
     *
     * @return null if the target object is null, the reference class is null, or
     * a primary key field name does not exist on the reference descriptor that
     * matches the target field name - otherwise, return the associated primary
     * key value
     */
    @Override
    public Object buildFieldValue(Object targetObject, XMLField xmlFld, AbstractSession session) {
        if (targetObject == null || getReferenceClass() == null) {
            return null;
        }
        ClassDescriptor descriptor = referenceDescriptor;
        if(null == descriptor) {
            descriptor = session.getClassDescriptor(targetObject);
        }
        ObjectBuilder objectBuilder = descriptor.getObjectBuilder();
        Object primaryKey = objectBuilder.extractPrimaryKeyFromObject(targetObject, session);
        int idx = 0;
        if(!(null == referenceClass || ClassConstants.OBJECT == getReferenceClass())) {
            idx = descriptor.getPrimaryKeyFields().indexOf(getSourceToTargetKeyFieldAssociations().get(xmlFld));
            if (idx == -1) {
                return null;
            }
        }
        if (primaryKey instanceof CacheId) {
            return ((CacheId)primaryKey).getPrimaryKey()[idx];
        } else {
            return primaryKey;
        }
    }

    /**
     * INTERNAL:
     * Create (if necessary) and populate a reference object that will be used
     * during the mapping reference resolution phase after unmarshalling is
     * complete.
     *
     */
    @Override
    public void buildReference(UnmarshalRecord record, XMLField xmlField, Object object, AbstractSession session) {
        ReferenceResolver resolver = record.getReferenceResolver();
        if (resolver == null) {
            return;
        }

        Object srcObject = record.getCurrentObject();
        // the order in which the primary keys are added to the vector is
        // relevant for cache lookup - it must match the ordering of the
        // reference descriptor's primary key entries

        Reference reference = resolver.getReference(this, srcObject);
        CacheId primaryKeys;
        if(null == referenceClass || ClassConstants.OBJECT == referenceClass) {
            if (reference == null) {
                // if reference is null, create a new instance and set it on the resolver
                primaryKeys = new CacheId(new Object[1]);
                reference = new Reference(this, srcObject, referenceClass, primaryKeys);
                resolver.addReference(reference);
                record.reference(reference);
            }  else {
                primaryKeys = (CacheId) reference.getPrimaryKey();
            }
            primaryKeys.set(0, object);
        } else {
            Vector<String> pkFieldNames = referenceDescriptor.getPrimaryKeyFieldNames();
            // if reference is null, create a new instance and set it on the resolver
            if (reference == null) {
                primaryKeys = new CacheId(new Object[pkFieldNames.size()]);
                reference = new Reference(this, srcObject, referenceClass, primaryKeys);
                resolver.addReference(reference);
                record.reference(reference);
            } else {
                primaryKeys = (CacheId) reference.getPrimaryKey();
            }
            XMLField tgtFld = (XMLField) getSourceToTargetKeyFieldAssociations().get(xmlField);
            int idx = pkFieldNames.indexOf(tgtFld.getQualifiedName());
            // fix for bug# 5687430
            // need to get the actual type of the target (i.e. int, String, etc.)
            // and use the converted value when checking the cache.
            Object value = session.getDatasourcePlatform().getConversionManager().convertObject(object, referenceDescriptor.getTypedField(tgtFld).getType());
            if (value != null) {
                primaryKeys.set(idx, value);
            }
        }
    }

    /**
     * INTERNAL:
     * Cascade perform delete through mappings that require the cascade
     */
    @Override
    public void cascadePerformRemoveIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        // objects referenced by this mapping are not registered as they have
        // no identity, however mappings from the referenced object may need cascading.
        Object objectReferenced = getRealAttributeValueFromObject(object, uow);
        if (objectReferenced == null) {
            return;
        }
        if (!visitedObjects.containsKey(objectReferenced)) {
            visitedObjects.put(objectReferenced, objectReferenced);
            ObjectBuilder builder = getReferenceDescriptor(objectReferenced.getClass(), uow).getObjectBuilder();
            builder.cascadePerformRemove(objectReferenced, uow, visitedObjects);
        }
    }

    /**
     * INTERNAL:
     * Cascade registerNew for Create through mappings that require the cascade
     */
    @Override
    public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow, Map visitedObjects) {
        // Aggregate objects are not registered but their mappings should be.
        Object objectReferenced = getRealAttributeValueFromObject(object, uow);
        if (objectReferenced == null) {
            return;
        }
        if (!visitedObjects.containsKey(objectReferenced)) {
            visitedObjects.put(objectReferenced, objectReferenced);
            ObjectBuilder builder = getReferenceDescriptor(objectReferenced.getClass(), uow).getObjectBuilder();
            builder.cascadeRegisterNewForCreate(objectReferenced, uow, visitedObjects);
        }
    }

    /**
     * INTERNAL:
     * Return a list of XMLFields based on the source XPath values
     * in the source-target key field associations list.
     */
    @Override
    public Vector getFields() {
        return sourceToTargetKeys;
    }

    /**
     * Return a QName representation the schema type for a given XMLField, if
     * applicable.
     *
     * Note:  This method performs the same functionality as 'getSchemaType' in
     * org.eclipse.persistence.internal.oxm.XMLSimpleMappingNodeValue.
     *
     */
    protected QName getSchemaType(XMLField xmlField, Object value, AbstractSession session) {
        QName schemaType = null;
        if (xmlField.isTypedTextField()) {
            ConversionManager conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
            schemaType = xmlField.getXMLType(value.getClass(), conversionManager);
        } else if (xmlField.isUnionField()) {
            return getSingleValueToWriteForUnion((XMLUnionField) xmlField, value, session);
        } else if (xmlField.getSchemaType() != null) {
            schemaType = xmlField.getSchemaType();
        }
        return schemaType;
    }

    /**
     * Return a single QName representation for a given XMLUnionField, if applicable.
     *
     * Note:  This method performs the same functionality as 'getSingleValueToWriteForUnion'
     * in org.eclipse.persistence.internal.oxm.XMLSimpleMappingNodeValue.
     *
     */
    protected QName getSingleValueToWriteForUnion(XMLUnionField xmlField, Object value, AbstractSession session) {
        ArrayList schemaTypes = xmlField.getSchemaTypes();
        QName schemaType = null;
        QName nextQName;
        Class javaClass;
        for (int i = 0; i < schemaTypes.size(); i++) {
            nextQName = (QName) (xmlField).getSchemaTypes().get(i);
            try {
                if (nextQName != null) {
                    ConversionManager conversionManager = (ConversionManager) session.getDatasourcePlatform().getConversionManager();
                    javaClass = xmlField.getJavaClass(nextQName, conversionManager);
                    conversionManager.convertObject(value, javaClass, nextQName);
                    schemaType = nextQName;
                    break;
                }
            } catch (ConversionException ce) {
                if (i == (schemaTypes.size() - 1)) {
                    schemaType = nextQName;
                }
            }
        }
        return schemaType;
    }

    /**
     * INTERNAL:
     * Return a list of source-target xmlfield pairs.
     *
     */
    @Override
    public HashMap getSourceToTargetKeyFieldAssociations() {
        return sourceToTargetKeyFieldAssociations;
    }

    /**
     * Return a string representation of a given value, based on a given schema type.
     *
     * Note:  This method performs the same functionality as 'getValueToWrite'
     * in org.eclipse.persistence.internal.oxm.XMLSimpleMappingNodeValue.
     *
     */
    protected String getValueToWrite(QName schemaType, Object value, AbstractSession session) {
        return ((XMLConversionManager) session.getDatasourcePlatform().getConversionManager()).convertObject(value, ClassConstants.STRING, schemaType);
    }

    /**
     * INTERNAL:
     * Register a ReferenceResolver as an event listener on the session,
     * if one doesn't already exist.  Each source/target field will have
     * a namespace resolver set as well.
     *
     * @see org.eclipse.persistence.internal.oxm.ReferenceResolver
     * @see org.eclipse.persistence.oxm.NamespaceResolver
     */
    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        if (null == referenceClass) {
            if(referenceClassName != null){
                setReferenceClass(session.getDatasourcePlatform().getConversionManager().convertClassNameToClass(referenceClassName));
            }
        }
        if(!(null == referenceClass || referenceClass == ClassConstants.OBJECT)) {
            super.initialize(session);
        }

        // iterate over each source & target XMLField and set the
        // appropriate namespace resolver
        XMLDescriptor descriptor = (XMLDescriptor) this.getDescriptor();
        XMLDescriptor targetDescriptor = (XMLDescriptor) getReferenceDescriptor();
        for (int index = 0; index < sourceToTargetKeys.size(); index++) {
            XMLField sourceField = (XMLField) sourceToTargetKeys.get(index);
            XMLField targetField = (XMLField) sourceToTargetKeyFieldAssociations.remove(sourceField);
            sourceField = (XMLField) descriptor.buildField(sourceField);
            sourceToTargetKeys.set(index, sourceField);
            if(null != targetField) {
                if(null == targetDescriptor) {
                    throw DescriptorException.referenceClassNotSpecified(this);
                }
                //primary key field from ref desc
                List<DatabaseField > pkFields  = targetDescriptor.getPrimaryKeyFields();
                for(int i=0; i<pkFields.size(); i++){
                    XMLField nextPKField = (XMLField)pkFields.get(i);
                    if(targetField.equals(nextPKField)){
                        targetField = (XMLField) targetDescriptor.buildField(nextPKField);
                        sourceField.setSchemaType(targetField.getSchemaType());
                        break;
                    }
                }

            }
            sourceToTargetKeyFieldAssociations.put(sourceField, targetField);
        }

        if (this.inverseReferenceMapping != null) {
            if (null != this.inverseReferenceMapping.getAttributeAccessor()) {
                this.inverseReferenceMapping.getAttributeAccessor().initializeAttributes(this.referenceClass);
            }
        }
    }

    @Override
    public void preInitialize(AbstractSession session) throws DescriptorException {
        getAttributeAccessor().setIsWriteOnly(this.isWriteOnly());
        getAttributeAccessor().setIsReadOnly(this.isReadOnly());
        super.preInitialize(session);
    }


    /**
     * INTERNAL:
     * Indicates that this is an XML mapping.
     */
    @Override
    public boolean isXMLMapping() {
        return true;
    }

    /**
     * INTERNAL:
     * Extract the primary key values from the row, then create an
     * org.eclipse.persistence.internal.oxm.Reference instance and store it
     * on the session's org.eclipse.persistence.internal.oxm.ReferenceResolver.
     */
    @Override
    public Object readFromRowIntoObject(AbstractRecord databaseRow, JoinedAttributeManager joinManager, Object targetObject, CacheKey parentCacheKey, ObjectBuildingQuery sourceQuery, AbstractSession executionSession, boolean isTargetProtected) throws DatabaseException {
        // the order in which the primary keys are added to the vector is
        // relevant for cache lookup - it must match the ordering of the
        // reference descriptor's primary key entries
        CacheId primaryKeys;
        ClassDescriptor descriptor = sourceQuery.getSession().getClassDescriptor(referenceClass);
        Vector pkFieldNames = null;
        if(null == descriptor) {
            primaryKeys = new CacheId(new Object[1]);
        } else {
            pkFieldNames = descriptor.getPrimaryKeyFieldNames();
            primaryKeys = new CacheId(new Object[pkFieldNames.size()]);
        }
        Iterator keyIt = sourceToTargetKeys.iterator();
        while (keyIt.hasNext()) {
            XMLField keyFld = (XMLField) keyIt.next();
            XMLField tgtFld = (XMLField) getSourceToTargetKeyFieldAssociations().get(keyFld);
            Object value;
            int idx = 0;
            if(null == tgtFld) {
               value = databaseRow.get(keyFld);
            } else {
                idx = pkFieldNames.indexOf(tgtFld.getXPath());
                if (idx == -1) {
                    continue;
                }
                // fix for bug# 5687430
                // need to get the actual type of the target (i.e. int, String, etc.)
                // and use the converted value when checking the cache.
                value = executionSession.getDatasourcePlatform().getConversionManager().convertObject(databaseRow.get(keyFld), descriptor.getTypedField(tgtFld).getType());
            }
            if (value != null) {
                primaryKeys.set(idx, value);
            }
        }
        // store the Reference instance on the resolver for use during mapping
        // resolution phase
        ReferenceResolver resolver = ((DOMRecord) databaseRow).getReferenceResolver();
        if (resolver != null) {
            resolver.addReference(new Reference(this, targetObject, referenceClass, primaryKeys));
        }
        return null;
    }

    /**
     */
    public void setField(DatabaseField field) {
        // do nothing.
    }

    /**
     * INTERNAL:
     * Set the list of source-target xmlfield pairs.
     */
    public void setSourceToTargetKeyFieldAssociations(HashMap sourceToTargetKeyFieldAssociations) {
        this.sourceToTargetKeyFieldAssociations = sourceToTargetKeyFieldAssociations;
    }

    /**
     * INTERNAL:
     * Write the attribute value from the object to the row.
     */
    @Override
    public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session, WriteType writeType) {
        // for each xmlField on this mapping
        Object targetObject = getAttributeValueFromObject(object);
        writeSingleValue(targetObject, object, (XMLRecord) row, session);
    }

    @Override
    public void writeSingleValue(Object value, Object parent, XMLRecord row, AbstractSession session) {
        for (Iterator fieldIt = getFields().iterator(); fieldIt.hasNext();) {
            XMLField xmlField = (XMLField) fieldIt.next();
            Object fieldValue = buildFieldValue(value, xmlField, session);
            if (fieldValue != null) {
                QName schemaType = getSchemaType(xmlField, fieldValue, session);
                String stringValue = getValueToWrite(schemaType, fieldValue, session);
                row.put(xmlField, stringValue);
            }
        }

    }

    @Override
    public void setIsWriteOnly(boolean b) {
        this.isWriteOnly = b;
    }

    @Override
    public boolean isWriteOnly() {
        return this.isWriteOnly;
    }

    @Override
    public void setAttributeValueInObject(Object object, Object value) throws DescriptorException {
        if(isWriteOnly()) {
            return;
        }
        super.setAttributeValueInObject(object, value);
    }

    @Override
    public XMLInverseReferenceMapping getInverseReferenceMapping() {
        return inverseReferenceMapping;
    }

    void setInverseReferenceMapping(XMLInverseReferenceMapping inverseReferenceMapping) {
        this.inverseReferenceMapping = inverseReferenceMapping;
    }
    @Override
    public boolean isObjectReferenceMapping() {
        return true;
    }

}
