/*
 * 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.internal.sessions.remote.ObjectDescriptor;
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<Object, ObjectDescriptor> objectDescriptors,
                                    Map<Object, Object> 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) {
    }

}
