/*
 * Copyright (c) 2011, 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:
//     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 jakarta.xml.bind.annotation.adapters.XmlAdapter;

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.ItemLinks;
import org.eclipse.persistence.internal.jpa.rs.metadata.model.Link;
import org.eclipse.persistence.internal.jpa.rs.weaving.PersistenceWeavedRest;
import org.eclipse.persistence.internal.jpa.rs.weaving.RestAdapterClassWriter;
import org.eclipse.persistence.internal.queries.CollectionContainerPolicy;
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.Session;
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 Session jpaSession;

    /**
     * Instantiates a new pre login mapping adapter.
     *
     * @param jpaSession the jpa session
     */
    public PreLoginMappingAdapter(Session jpaSession) {
        this.jpaSession = jpaSession;
    }

    /* (non-Javadoc)
     * @see org.eclipse.persistence.internal.jaxb.SessionEventListener#preLogin(org.eclipse.persistence.sessions.SessionEvent)
     */
    @Override
    @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 = 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);

            XMLCompositeObjectMapping itemLinksMapping = new XMLCompositeObjectMapping();
            itemLinksMapping.setAttributeName("_persistence_links");
            itemLinksMapping.setGetMethodName("_persistence_getLinks");
            itemLinksMapping.setSetMethodName("_persistence_setLinks");
            itemLinksMapping.setDescriptor(descriptor);
            itemLinksMapping.setReferenceClass(ItemLinks.class);
            itemLinksMapping.setXPath(".");
            descriptor.addMapping(itemLinksMapping);

            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.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 (!isAbstract) {
                                InstantiationPolicy instantiationPolicy = new InstantiationPolicy();
                                instantiationPolicy.useFactoryInstantiationPolicy(new ConcreteSubclassFactory(subClassToInstantiate), "createConcreteSubclass");
                                descriptor.setInstantiationPolicy(instantiationPolicy);
                                break;
                            }
                        }
                    }
                }
            }
        }

        for (Object descriptorAlias : project.getAliasDescriptors().keySet()) {
            ClassDescriptor descriptor = 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;
                                ClassDescriptor jaxbDescriptor = project.getDescriptorForAlias(jpaMapping.getDescriptor().getAlias());
                                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;
                            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
     */
    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
     */
    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, Session 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<? extends XmlAdapter<?,?>>) 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<? extends XmlAdapter<?,?>>) Class.forName(adapterClassName, true, cl)));
                        jaxbDescriptor.removeMappingForAttributeName(jaxbMapping.getAttributeName());
                        jaxbDescriptor.addMapping(xmlChoiceMapping);
                    }
                } catch (Exception ex) {
                    throw JPARSException.exceptionOccurred(ex);
                }
            }
        }
    }
}
