/*
 * 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:
//     rbarkhouse - 2009-11-26 13:04:58 - 2.0 - initial implementation
package org.eclipse.persistence.oxm.mappings;

import java.util.Collection;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.oxm.mappings.InverseReferenceMapping;
import org.eclipse.persistence.internal.oxm.record.XMLRecord;
import org.eclipse.persistence.internal.queries.CollectionContainerPolicy;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.JoinedAttributeManager;
import org.eclipse.persistence.internal.queries.ListContainerPolicy;
import org.eclipse.persistence.internal.queries.MapContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.ContainerMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.ObjectBuildingQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.remote.DistributedSession;

/**
 * This mapping is used to map a back-pointer.  It represents the "opposite" of one of the
 * following relationship mappings:<br><br>
 *
 * <ul>
 * <li>XMLCompositeObjectMapping
 * <li>XMLCompositeCollectionMapping
 * <li>XMLObjectReferenceMapping
 * <li>XMLCollectionReferenceMapping
 * </ul>
 *
 * When configuring an XMLInverseReferenceMapping, the "mappedBy" field must be set to the
 * field on the reference class that maps to this Descriptor.  For example:<br><br>
 *
 * <code>
 * // EMPLOYEE has a collection of PHONEs (phoneNumbers)<br>
 * // PHONE has a back-pointer to EMPLOYEE (owningEmployee)<br><br>
 *
 * // EMPLOYEE Descriptor<br>
 * XMLCompositeCollectionMapping phone = new XMLCompositeCollectionMapping();<br>
 * phone.setReferenceClassName("org.example.PhoneNumber");<br>
 * phone.setAttributeName("phoneNumbers");<br>
 * ...<br><br>
 *
 * // PHONE Descriptor<br>
 * XMLInverseReferenceMapping owningEmployee = new XMLInverseReferenceMapping();<br>
 * owningEmployee.setReferenceClassName("org.example.Employee");<br>
 * owningEmployee.setMappedBy("phoneNumbers");<br>
 * owningEmployee.setAttributeName("owningEmployee");<br>
 * ...<br>
 * </code>
 */
public class XMLInverseReferenceMapping extends AggregateMapping implements InverseReferenceMapping<AbstractSession, AttributeAccessor, ContainerPolicy, ClassDescriptor, DatabaseField, DatabaseMapping, XMLRecord>, ContainerMapping {

    private String mappedBy;
    private ContainerPolicy containerPolicy;
    private DatabaseMapping inlineMapping;

    @Override
    public boolean isXMLMapping() {
        return true;
    }

    @Override
    public void initialize(AbstractSession session) throws DescriptorException {
        super.initialize(session);
        setFields(new Vector<>());
        if(inlineMapping != null){
            inlineMapping.initialize(session);
        }
    }

    @Override
    public void preInitialize(AbstractSession session){
        super.preInitialize(session);
        if(inlineMapping != null){
            inlineMapping.setDescriptor(this.descriptor);
            inlineMapping.preInitialize(session);
        }
    }

    @Override
    public void postInitialize(AbstractSession session) throws DescriptorException {
        // Get the corresponding mapping from the reference descriptor and set up the
        // inverse mapping.
        DatabaseMapping mapping = getReferenceDescriptor().getMappingForAttributeName(this.mappedBy);

        if (mapping instanceof XMLInverseReferenceMapping) {
            mapping  = ((XMLInverseReferenceMapping)mapping).getInlineMapping();
        }

        if (mapping instanceof XMLCompositeCollectionMapping) {
            XMLCompositeCollectionMapping oppositeMapping = (XMLCompositeCollectionMapping) mapping;
            oppositeMapping.setInverseReferenceMapping(this);
        }

        if (mapping instanceof XMLCompositeObjectMapping) {
            XMLCompositeObjectMapping oppositeMapping = (XMLCompositeObjectMapping) mapping;
            oppositeMapping.setInverseReferenceMapping(this);
        }

        if (mapping instanceof XMLObjectReferenceMapping) {
            XMLObjectReferenceMapping oppositeMapping = (XMLObjectReferenceMapping) mapping;
            oppositeMapping.setInverseReferenceMapping(this);
        }

        if (mapping instanceof XMLChoiceObjectMapping) {
            XMLChoiceObjectMapping oppositeMapping = (XMLChoiceObjectMapping) mapping;
            Collection<XMLMapping> nestedMappings = oppositeMapping.getChoiceElementMappings().values();
            for(XMLMapping next:nestedMappings) {
                if(next instanceof XMLCompositeObjectMapping) {
                    XMLCompositeObjectMapping compositeMapping = ((XMLCompositeObjectMapping)next);
                    if(compositeMapping.getReferenceClass() == this.getDescriptor().getJavaClass() || this.getDescriptor().getJavaClass().isAssignableFrom(compositeMapping.getReferenceClass())) {
                        compositeMapping.setInverseReferenceMapping(this);
                    }
                } else if(next instanceof XMLObjectReferenceMapping) {
                    XMLObjectReferenceMapping refMapping = ((XMLObjectReferenceMapping)next);
                    if(refMapping.getReferenceClass() == this.getDescriptor().getJavaClass()) {
                        refMapping.setInverseReferenceMapping(this);
                    }
                }
            }
        }

        if (mapping instanceof XMLChoiceCollectionMapping) {
            XMLChoiceCollectionMapping oppositeMapping = (XMLChoiceCollectionMapping) mapping;
            Collection<XMLMapping> nestedMappings = oppositeMapping.getChoiceElementMappings().values();
            for(XMLMapping next:nestedMappings) {
                if(next instanceof XMLCompositeCollectionMapping) {
                    XMLCompositeCollectionMapping compositeMapping = ((XMLCompositeCollectionMapping)next);
                    if(compositeMapping.getReferenceClass() == this.getDescriptor().getJavaClass() || this.getDescriptor().getJavaClass().isAssignableFrom(compositeMapping.getReferenceClass())) {
                        compositeMapping.setInverseReferenceMapping(this);
                    }
                } else if(next instanceof XMLCollectionReferenceMapping) {
                    XMLCollectionReferenceMapping refMapping = ((XMLCollectionReferenceMapping)next);
                    if(refMapping.getReferenceClass() == this.getDescriptor().getJavaClass()) {
                        refMapping.setInverseReferenceMapping(this);
                    }
                }
            }
        }

        if(inlineMapping != null){
            inlineMapping.postInitialize(session);
        }
    }

    public String getMappedBy() {
        return mappedBy;
    }

    @Override
    public void setMappedBy(String mappedBy) {
        this.mappedBy = mappedBy;
    }

    // == AggregateMapping methods ============================================

    @Override
    public void buildBackupClone(Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
    }

    @Override
    public void buildClone(Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession) {
    }

    @Override
    public void buildCloneFromRow(AbstractRecord databaseRow,
            JoinedAttributeManager joinManager, Object clone, CacheKey sharedCacheKey,
            ObjectBuildingQuery sourceQuery, UnitOfWorkImpl unitOfWork,
            AbstractSession executionSession) {
    }

    @Override
    public void cascadePerformRemoveIfRequired(Object object,
            UnitOfWorkImpl uow, Map visitedObjects) {
    }

    @Override
    public void cascadeRegisterNewIfRequired(Object object, UnitOfWorkImpl uow,
            Map visitedObjects) {
    }

    @Override
    public ChangeRecord compareForChange(Object clone, Object backup,
            ObjectChangeSet owner, AbstractSession session) {
        return null;
    }

    @Override
    public boolean compareObjects(Object firstObject, Object secondObject,
            AbstractSession session) {
        return false;
    }

    @Override
    public void fixObjectReferences(Object object, Map objectDescriptors,
            Map processedObjects, ObjectLevelReadQuery query,
            DistributedSession session) {
    }

    @Override
    public void iterate(DescriptorIterator iterator) {
    }

    @Override
    public void mergeChangesIntoObject(Object target,
            ChangeRecord changeRecord, Object source, MergeManager mergeManager, AbstractSession targetSession) {
    }

    @Override
    public void mergeIntoObject(Object target, boolean isTargetUninitialized,
            Object source, MergeManager mergeManager, AbstractSession targetSession) {
    }

    // == ContainerPolicy methods =============================================

    @Override
    public void setContainerPolicy(ContainerPolicy containerPolicy) {
        this.containerPolicy = containerPolicy;
    }

    @Override
    public ContainerPolicy getContainerPolicy() {
        return this.containerPolicy;
    }

    @Override
    public void useCollectionClass(Class concreteClass) {
        this.containerPolicy = new CollectionContainerPolicy(concreteClass);
    }

    @Override
    public void useCollectionClassName(String concreteClass) {
        this.containerPolicy = new CollectionContainerPolicy(concreteClass);
    }

    @Override
    public void useListClassName(String concreteClass) {
        this.containerPolicy = new ListContainerPolicy(concreteClass);
    }

    @Override
    public void useMapClass(Class concreteClass, String methodName) {
        this.containerPolicy = new MapContainerPolicy(concreteClass);
    }

    @Override
    public void useMapClassName(String concreteClass, String methodName) {
        this.containerPolicy = new MapContainerPolicy(concreteClass);
    }

    @Override
    public DatabaseMapping getInlineMapping() {
        return inlineMapping;
    }

    @Override
    public void setInlineMapping(DatabaseMapping inlineMapping) {
        this.inlineMapping = inlineMapping;
    }

    @Override
    public void writeSingleValue(Object value, Object object, XMLRecord record, AbstractSession session) {
    }

}
