/*******************************************************************************
 * Copyright (c) 2011, 2013 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
 * which accompanies this distribution.
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     tware -  Initial implementation
 ******************************************************************************/
package org.eclipse.persistence.jpa.rs.util;

import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.descriptors.VirtualAttributeAccessor;
import org.eclipse.persistence.internal.dynamic.ValuesAccessor;
import org.eclipse.persistence.internal.jaxb.SessionEventListener;
import org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.Link;
import org.eclipse.persistence.internal.jpa.weaving.RestAdapterClassWriter;
import org.eclipse.persistence.internal.queries.CollectionContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.weaving.PersistenceWeavedRest;
import org.eclipse.persistence.jaxb.DefaultXMLNameTransformer;
import org.eclipse.persistence.jpa.rs.exceptions.JPARSException;
import org.eclipse.persistence.jpa.rs.util.xmladapters.RelationshipLinkAdapter;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.XMLChoiceCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLChoiceObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLInverseReferenceMapping;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.SessionEvent;

/**
 * This adapter alters the way the JAXBContext handles relationships for an existing persistence unit.
 * It changes non-private relationship mappings to be read-only and replaces those mappings with a mapping 
 * to a weaved-in list of relationships that will produce links.
 * @author tware
 *
 */
public class PreLoginMappingAdapter extends SessionEventListener {

    protected AbstractSession jpaSession;

    /**
     * Instantiates a new pre login mapping adapter.
     *
     * @param jpaSession the jpa session
     */
    public PreLoginMappingAdapter(AbstractSession jpaSession) {
        this.jpaSession = jpaSession;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.internal.jaxb.SessionEventListener#preLogin(org.eclipse.persistence.sessions.SessionEvent)
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void preLogin(SessionEvent event) {
        Project project = event.getSession().getProject();
        ClassLoader cl = jpaSession.getDatasourcePlatform().getConversionManager().getLoader();
        DefaultXMLNameTransformer xmlNameTransformer = new DefaultXMLNameTransformer();	
        for (Object descriptorAlias : project.getAliasDescriptors().keySet()) {
            ClassDescriptor descriptor = (ClassDescriptor) project.getAliasDescriptors().get(descriptorAlias);

            if (!PersistenceWeavedRest.class.isAssignableFrom(descriptor.getJavaClass())) {
                continue;
            }

            if (descriptor.isXMLDescriptor()) {
                XMLDescriptor xmlDescriptor = (XMLDescriptor) project.getAliasDescriptors().get(descriptorAlias);
                if (null != xmlDescriptor) {
                    if (null == xmlDescriptor.getDefaultRootElement()) {
                        // set root element 
                        xmlDescriptor.setDefaultRootElement(xmlNameTransformer.transformRootElementName(xmlDescriptor.getJavaClass().getName()));
                        // set resultAlwaysXMLRoot to false, so that the elements are not wrapped in JAXBElements when unmarshalling.
                        xmlDescriptor.setResultAlwaysXMLRoot(false);
                    }
                }
            }

            XMLCompositeCollectionMapping relationshipMapping = new XMLCompositeCollectionMapping();
            relationshipMapping.setAttributeName("_persistence_relationshipInfo");
            relationshipMapping.setGetMethodName("_persistence_getRelationships");
            relationshipMapping.setSetMethodName("_persistence_setRelationships");
            relationshipMapping.setDescriptor(descriptor);
            CollectionContainerPolicy containerPolicy = new CollectionContainerPolicy(ArrayList.class);
            relationshipMapping.setContainerPolicy(containerPolicy);
            relationshipMapping.setField(new XMLField("_relationships"));
            relationshipMapping.setReferenceClass(Link.class);
            XMLJavaTypeConverter converter = new XMLJavaTypeConverter(RelationshipLinkAdapter.class);
            converter.initialize(relationshipMapping, event.getSession());
            relationshipMapping.setConverter(converter);
            descriptor.addMapping(relationshipMapping);

            XMLCompositeObjectMapping hrefMapping = new XMLCompositeObjectMapping();
            hrefMapping.setAttributeName("_persistence_href");
            hrefMapping.setGetMethodName("_persistence_getHref");
            hrefMapping.setSetMethodName("_persistence_setHref");
            hrefMapping.setDescriptor(descriptor);
            hrefMapping.setField(new XMLField("_link"));
            hrefMapping.setReferenceClass(Link.class);
            hrefMapping.setXPath(".");
            descriptor.addMapping(hrefMapping);

            ClassDescriptor jpaDescriptor = jpaSession.getDescriptorForAlias(descriptor.getAlias());
            Vector<DatabaseMapping> descriptorMappings = (Vector<DatabaseMapping>) descriptor.getMappings().clone();
            for (DatabaseMapping mapping : descriptorMappings) {
                if (mapping.isXMLMapping()) {
                    if (mapping.isAbstractCompositeObjectMapping() || mapping.isAbstractCompositeCollectionMapping()) {
                        if (mapping.isAbstractCompositeCollectionMapping()) {
                            XMLInverseReferenceMapping inverseMapping = ((XMLCompositeCollectionMapping) mapping).getInverseReferenceMapping();
                            if (inverseMapping != null) {
                                break;
                            }
                        } else if (mapping.isAbstractCompositeObjectMapping()) {
                            XMLInverseReferenceMapping inverseMapping = ((XMLCompositeObjectMapping) mapping).getInverseReferenceMapping();
                            if (inverseMapping != null) {
                                break;
                            }
                        }

                        if (jpaDescriptor != null) {
                            DatabaseMapping dbMapping = jpaDescriptor.getMappingForAttributeName(mapping.getAttributeName());
                            if ((dbMapping != null) && (dbMapping instanceof ForeignReferenceMapping)) {
                                ForeignReferenceMapping jpaMapping = (ForeignReferenceMapping) dbMapping;
                                if (jpaMapping != null) {
                                    if (jpaMapping.getMappedBy() != null) {
                                        ClassDescriptor inverseDescriptor = project.getDescriptorForAlias(jpaMapping.getReferenceDescriptor().getAlias());
                                        if (inverseDescriptor != null) {
                                            DatabaseMapping inverseMapping = inverseDescriptor.getMappingForAttributeName(jpaMapping.getMappedBy());
                                            if (inverseMapping != null) {
                                                convertMappingToXMLInverseReferenceMapping(inverseDescriptor, inverseMapping, jpaMapping);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            InheritancePolicy inheritancePolicy = descriptor.getInheritancePolicyOrNull();
            if ((inheritancePolicy != null) && (inheritancePolicy.isRootParentDescriptor())) {
                boolean isAbstract = Modifier.isAbstract(descriptor.getJavaClass().getModifiers());
                if (isAbstract) {
                    Class subClassToInstantiate = null;
                    Map<?, ?> classIndicatorMapping = inheritancePolicy.getClassIndicatorMapping();
                    // get one of subclasses that extends this abstract class
                    for (Map.Entry<?, ?> entry : classIndicatorMapping.entrySet()) {
                        Object value = entry.getValue();
                        if (value instanceof Class) {
                            subClassToInstantiate = (Class) value;
                            isAbstract = Modifier.isAbstract(subClassToInstantiate.getModifiers());
                            if ((subClassToInstantiate != null) && (!isAbstract)) {
                                InstantiationPolicy instantiationPolicy = new InstantiationPolicy();
                                instantiationPolicy.useFactoryInstantiationPolicy(new ConcreteSubclassFactory(subClassToInstantiate), "createConcreteSubclass");
                                descriptor.setInstantiationPolicy(instantiationPolicy);
                                break;
                            }
                        }
                    }
                }
            }
        }

        for (Object descriptorAlias : project.getAliasDescriptors().keySet()) {
            ClassDescriptor descriptor = (ClassDescriptor) project.getAliasDescriptors().get(descriptorAlias);
            ClassDescriptor jpaDescriptor = jpaSession.getDescriptorForAlias(descriptor.getAlias());
            Vector<DatabaseMapping> descriptorMappings = (Vector<DatabaseMapping>) descriptor.getMappings().clone();

            for (DatabaseMapping mapping : descriptorMappings) {
                if (mapping.isXMLMapping()) {
                    if (mapping.isAbstractCompositeObjectMapping() || mapping.isAbstractCompositeCollectionMapping()) {
                        if (jpaDescriptor != null) {
                            DatabaseMapping dbMapping = jpaDescriptor.getMappingForAttributeName(mapping.getAttributeName());
                            if ((dbMapping instanceof ForeignReferenceMapping)) {
                                ForeignReferenceMapping jpaMapping = (ForeignReferenceMapping) dbMapping;
                                if (jpaMapping != null) {
                                    ClassDescriptor jaxbDescriptor = project.getDescriptorForAlias(jpaMapping.getDescriptor().getAlias());
                                    if (jaxbDescriptor != null) {
                                        convertMappingToXMLChoiceMapping(jaxbDescriptor, jpaMapping, cl, jpaSession);
                                    }
                                }
                            }
                        } else if (mapping instanceof XMLCompositeObjectMapping) {
                            // Fix for Bug 403113 - JPA-RS Isn't Serializing an Embeddable defined in an ElementCollection to JSON Correctly 
                            // add choice mapping for one-to-one relationships within embeddables
                            // Based on (http://wiki.eclipse.org/EclipseLink/Examples/JPA/NoSQL#Step_2_:_Map_the_data), 
                            // the mappedBy option on relationships is not supported for NoSQL data, so no need to add inverse mapping
                            XMLCompositeObjectMapping jpaMapping = (XMLCompositeObjectMapping) mapping;
                            if (jpaMapping != null) {
                                ClassDescriptor jaxbDescriptor = project.getDescriptorForAlias(jpaMapping.getDescriptor().getAlias());
                                if (jaxbDescriptor != null) {
                                    Class clazz = jpaMapping.getReferenceClass();
                                    if (clazz != null) {
                                        if ((jpaSession.getDescriptor(clazz) != null) && (jpaSession.getDescriptor(clazz).isEISDescriptor()))
                                            convertMappingToXMLChoiceMapping(jaxbDescriptor, jpaMapping, cl, jpaSession);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }



    /**
     * Update the targetMapping to have the same accessor as the originMapping
     * @param originMapping
     * @param targetMapping
     */
    private static void copyAccessorToMapping(DatabaseMapping originMapping, DatabaseMapping targetMapping) {
        if (originMapping.getAttributeAccessor().isVirtualAttributeAccessor()) {
            VirtualAttributeAccessor accessor = new VirtualAttributeAccessor();
            accessor.setGetMethodName(originMapping.getGetMethodName());
            accessor.setSetMethodName(originMapping.getSetMethodName());
            targetMapping.setAttributeAccessor(accessor);
        }
        if (originMapping.getAttributeAccessor().isValuesAccessor()) {
            ValuesAccessor accessor = new ValuesAccessor(originMapping);
            accessor.setAttributeName(originMapping.getAttributeAccessor().getAttributeName());
            targetMapping.setAttributeAccessor(accessor);
        } else {
            targetMapping.setAttributeName(originMapping.getAttributeName());
            targetMapping.setGetMethodName(originMapping.getGetMethodName());
            targetMapping.setSetMethodName(originMapping.getSetMethodName());
        }
    }

    /**
     * Build an XMLInverseMapping based on a particular mapping and replace that mapping with
     * the newly created XMLInverseMapping in jaxbDescriptor
     * @param jaxbDescriptor
     * @param mapping
     * @param mappedBy
     */
    private static void convertMappingToXMLInverseReferenceMapping(ClassDescriptor jaxbDescriptor, DatabaseMapping mapping, ForeignReferenceMapping jpaMapping) {
        if ((mapping != null) && (jaxbDescriptor != null)) {
            if (!(mapping.isXMLMapping())) {
                return;
            }

            if ((jpaMapping.isAggregateCollectionMapping()) || (jpaMapping.isAggregateMapping())) {
                return;
            }

            XMLInverseReferenceMapping jaxbInverseMapping = new XMLInverseReferenceMapping();
            copyAccessorToMapping(mapping, jaxbInverseMapping);
            jaxbInverseMapping.setProperties(mapping.getProperties());
            jaxbInverseMapping.setIsReadOnly(mapping.isReadOnly());
            jaxbInverseMapping.setMappedBy(jpaMapping.getAttributeName());

            if (mapping.isAbstractCompositeCollectionMapping()) {
                jaxbInverseMapping.setContainerPolicy(mapping.getContainerPolicy());
                jaxbInverseMapping.setReferenceClass(((XMLCompositeCollectionMapping) mapping).getReferenceClass());
            } else if (mapping.isAbstractCompositeObjectMapping()) {
                jaxbInverseMapping.setReferenceClass(((XMLCompositeObjectMapping) mapping).getReferenceClass());
            }

            jaxbDescriptor.removeMappingForAttributeName(mapping.getAttributeName());
            jaxbDescriptor.addMapping(jaxbInverseMapping);
        }
    }

    /**
     * Build an XMLChoiceObjectMapping based on a particular mapping and replace that mapping with
     * the newly created XMLChoiceObjectMapping in jaxbDescriptor.
     * @param jaxbDescriptor the jaxb descriptor
     * @param jpaMapping the jpa mapping
     * @param cl the classloader
     */
    @SuppressWarnings("rawtypes")
    private static void convertMappingToXMLChoiceMapping(ClassDescriptor jaxbDescriptor, DatabaseMapping jpaMapping, ClassLoader cl, AbstractSession jpaSession) {
        if ((jpaMapping != null) && (jaxbDescriptor != null)) {
            if ((jpaMapping instanceof ForeignReferenceMapping) && ((jpaMapping.isAggregateCollectionMapping()) || (jpaMapping.isAggregateMapping()))) {
                // Fix for Bug 402385 - JPA-RS: ClassNotFound when using ElementCollection of Embeddables
                // Aggregates don't have identity to create links, thus no weaved REST adapters to insert choice mappings   
                return;
            }

            String attributeName = jpaMapping.getAttributeName();
            DatabaseMapping jaxbMapping = jaxbDescriptor.getMappingForAttributeName(jpaMapping.getAttributeName());
            if (!(jaxbMapping.isXMLMapping() && (jaxbMapping.isAbstractCompositeCollectionMapping() || jaxbMapping.isAbstractCompositeObjectMapping()))) {
                return;
            }

            ClassDescriptor refDesc = null;

            if (jpaMapping instanceof ForeignReferenceMapping) {
                Class clazz = ((ForeignReferenceMapping) jpaMapping).getReferenceClass();
                refDesc = jpaSession.getDescriptor(clazz);
            } else if (jpaMapping instanceof XMLCompositeObjectMapping) {
                Class clazz = ((XMLCompositeObjectMapping) jpaMapping).getReferenceClass();
                refDesc = jpaSession.getDescriptor(clazz);
            }

            if (refDesc == null) {
                return;
            }

            String adapterClassName = RestAdapterClassWriter.constructClassNameForReferenceAdapter(refDesc.getJavaClassName());
            if (adapterClassName != null) {
                try {
                    if (jaxbMapping.isAbstractCompositeObjectMapping()) {
                        XMLChoiceObjectMapping xmlChoiceMapping = new XMLChoiceObjectMapping();
                        xmlChoiceMapping.setAttributeName(attributeName);
                        copyAccessorToMapping(jaxbMapping, xmlChoiceMapping);
                        xmlChoiceMapping.setProperties(jaxbMapping.getProperties());

                        XMLCompositeObjectMapping compositeMapping = (XMLCompositeObjectMapping) jaxbMapping;
                        xmlChoiceMapping.addChoiceElement(compositeMapping.getXPath(), Link.class);
                        xmlChoiceMapping.addChoiceElement(compositeMapping.getXPath(), refDesc.getJavaClass());

                        xmlChoiceMapping.setConverter(new XMLJavaTypeConverter(Class.forName(adapterClassName, true, cl)));
                        jaxbDescriptor.removeMappingForAttributeName(jaxbMapping.getAttributeName());
                        jaxbDescriptor.addMapping(xmlChoiceMapping);

                    } else if (jaxbMapping.isAbstractCompositeCollectionMapping()) {
                        XMLChoiceCollectionMapping xmlChoiceMapping = new XMLChoiceCollectionMapping();
                        xmlChoiceMapping.setAttributeName(attributeName);
                        copyAccessorToMapping(jaxbMapping, xmlChoiceMapping);
                        xmlChoiceMapping.setProperties(jaxbMapping.getProperties());

                        XMLCompositeCollectionMapping compositeMapping = (XMLCompositeCollectionMapping) jaxbMapping;
                        xmlChoiceMapping.addChoiceElement(compositeMapping.getXPath(), Link.class);
                        xmlChoiceMapping.addChoiceElement(compositeMapping.getXPath(), refDesc.getJavaClass());

                        xmlChoiceMapping.setContainerPolicy(jaxbMapping.getContainerPolicy());
                        xmlChoiceMapping.setConverter(new XMLJavaTypeConverter(Class.forName(adapterClassName, true, cl)));
                        jaxbDescriptor.removeMappingForAttributeName(jaxbMapping.getAttributeName());
                        jaxbDescriptor.addMapping(xmlChoiceMapping);
                    }
                } catch (ClassNotFoundException e) {
                    throw new JPARSException(e.toString());
                }
            }
        }
    }
}
