/*
 * 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:
//     Denise Smith -  January, 2010 - 2.0.1
package org.eclipse.persistence.jaxb.compiler;

import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlList;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import org.eclipse.persistence.internal.jaxb.AccessorFactoryWrapper;
import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.jaxb.javamodel.Helper;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaField;
import org.eclipse.persistence.jaxb.javamodel.JavaMethod;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaClassImpl;
import org.eclipse.persistence.jaxb.xmlmodel.XmlJoinNodes;

/**
 * Helper class for code that needs to be shared between AnnotationsProcessor,
 * MappingsGenerator, SchemaGenerator
 */
public class CompilerHelper {

    public static final String XML_LOCATION_ANNOTATION_NAME = "org.glassfish.jaxb.core.annotation.XmlLocation";
    public static final String OLD_XML_LOCATION_ANNOTATION_NAME = "com.sun.xml.bind.annotation.XmlLocation";
    public static final String INTERNAL_XML_LOCATION_ANNOTATION_NAME = "com.sun.xml.internal.bind.annotation.XmlLocation";

    private static final String XML_ACCESSOR_FACTORY_ANNOTATION_NAME = "org.glassfish.jaxb.runtime.XmlAccessorFactory";
    private static final String OLD_ACCESSOR_FACTORY_ANNOTATION_NAME = "com.sun.xml.bind.XmlAccessorFactory";
    private static final String INTERNAL_ACCESSOR_FACTORY_ANNOTATION_NAME = "com.sun.xml.internal.bind.XmlAccessorFactory";
    private static final String METADATA_MODEL_PACKAGE = "org.eclipse.persistence.jaxb.xmlmodel";

    public static Class ACCESSOR_FACTORY_ANNOTATION_CLASS = null;
    public static Method ACCESSOR_FACTORY_VALUE_METHOD = null;
    public static Class OLD_ACCESSOR_FACTORY_ANNOTATION_CLASS = null;
    public static Method OLD_ACCESSOR_FACTORY_VALUE_METHOD = null;
    public static Class INTERNAL_ACCESSOR_FACTORY_ANNOTATION_CLASS = null;
    public static Method INTERNAL_ACCESSOR_FACTORY_VALUE_METHOD = null;
    public static Class XML_LOCATION_ANNOTATION_CLASS = null;
    public static Class OLD_XML_LOCATION_ANNOTATION_CLASS = null;
    public static Class INTERNAL_XML_LOCATION_ANNOTATION_CLASS = null;

    private static JAXBContext xmlBindingsModelContext;

    static {
        try {
            ACCESSOR_FACTORY_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(XML_ACCESSOR_FACTORY_ANNOTATION_NAME, true, CompilerHelper.class.getClassLoader());
            ACCESSOR_FACTORY_VALUE_METHOD = PrivilegedAccessHelper.getDeclaredMethod(ACCESSOR_FACTORY_ANNOTATION_CLASS, "value", new Class[]{});
        } catch (Exception ex) {
        }

        try {
            XML_LOCATION_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(XML_LOCATION_ANNOTATION_NAME, true, CompilerHelper.class.getClassLoader());
        } catch (Exception ex) {
        }

        try {
            OLD_XML_LOCATION_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(OLD_XML_LOCATION_ANNOTATION_NAME, true, CompilerHelper.class.getClassLoader());
        } catch (Exception ex) {
        }

        try{
            OLD_ACCESSOR_FACTORY_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(OLD_ACCESSOR_FACTORY_ANNOTATION_NAME);
            OLD_ACCESSOR_FACTORY_VALUE_METHOD = PrivilegedAccessHelper.getDeclaredMethod(OLD_ACCESSOR_FACTORY_ANNOTATION_CLASS, "value", new Class[]{});
        } catch (Exception ex) {
        }

        try{
            INTERNAL_ACCESSOR_FACTORY_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(INTERNAL_ACCESSOR_FACTORY_ANNOTATION_NAME);
            INTERNAL_ACCESSOR_FACTORY_VALUE_METHOD = PrivilegedAccessHelper.getDeclaredMethod(INTERNAL_ACCESSOR_FACTORY_ANNOTATION_CLASS, "value", new Class[]{});
        } catch (Exception ex) {
        }

        try{
            INTERNAL_XML_LOCATION_ANNOTATION_CLASS = PrivilegedAccessHelper.getClassForName(INTERNAL_XML_LOCATION_ANNOTATION_NAME);
        }catch (Exception ex) {
        }


    }

    /**
     * If 2 TypeMappingInfo objects would generate the same generated class (and
     * therefore complex type) then return the existing class otherwise return
     * null.
     */
    static Class getExisitingGeneratedClass(TypeMappingInfo tmi, Map<TypeMappingInfo, Class> typeMappingInfoToGeneratedClasses, Map<TypeMappingInfo, Class> typeMappingInfoToAdapterClasses, ClassLoader loader) {

        Iterator<Map.Entry<TypeMappingInfo, Class>> iter = typeMappingInfoToGeneratedClasses.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry<TypeMappingInfo, Class> next = iter.next();
            TypeMappingInfo nextTMI = next.getKey();
            if (CompilerHelper.generatesSameComplexType(tmi, nextTMI, loader)) {
                return next.getValue();
            }
        }
        return null;
    }

    /**
     * Return true if the two TypeMappingInfoObjects should generate the same
     * complex type in the XSD
     */
    private static boolean generatesSameComplexType(TypeMappingInfo tmi1, TypeMappingInfo tmi2, ClassLoader loader) {

        org.eclipse.persistence.jaxb.xmlmodel.XmlElement element1 = null;
        org.eclipse.persistence.jaxb.xmlmodel.XmlElement element2 = null;

        if (tmi1.getXmlElement() != null) {
            element1 = getXmlElement(tmi1.getXmlElement(), loader);
        }

        if (tmi2.getXmlElement() != null) {
            element2 = getXmlElement(tmi2.getXmlElement(), loader);
        }

        Type actualType1 = getActualType(tmi1, element1);
        Type actualType2 = getActualType(tmi2, element2);

        if (!areTypesEqual(actualType1, actualType2)) {
            return false;
        }

        if (!hasSameClassName(tmi1,tmi2)) {
            return false;
        }

        boolean isXmlList1 = isXmlList(tmi1, element1);
        boolean isXmlList2 = isXmlList(tmi2, element2);

        if (isXmlList1) {
            if (!isXmlList2) {
                return false;
            }
        } else if (isXmlList2) {
            return false;
        }

        return true;
    }

    /**
     * Return true if tmi1 and tmi2 are instances of Class and have same class name.
     *
     * @param tmi1 instance of TypeMappingInfo
     * @param tmi2 instance of typeMappingInfo
     * @return true if TypeMappingInfos are instances of Class and have same class name
     */
    private static boolean hasSameClassName(TypeMappingInfo tmi1, TypeMappingInfo tmi2) {

        Type type1 = tmi1.getType();
        Type type2 = tmi2.getType();

        if (type1 != null && type2 == null) {
            return false;
        } else if (type1 == null && type2 != null) {
            return false;
        } else if (type1 instanceof Class && type2 instanceof Class){

            String typeName1 = ((Class)type1).getName();
            String typeName2 = ((Class)type2).getName();

            if (!typeName1.equals(typeName2)) {
                return false;
            }
        }

        return true;
    }

    /**
     * Return if this TypeMappingInfo has an XmlList annotation or is specified
     * to be an xmlList in an XMLElement override
     */
    private static boolean isXmlList(TypeMappingInfo tmi, org.eclipse.persistence.jaxb.xmlmodel.XmlElement element) {
        if (element != null && element.isXmlList()) {
            return true;
        }

        if (tmi.getAnnotations() != null) {
            for (int i = 0; i < tmi.getAnnotations().length; i++) {
                java.lang.annotation.Annotation nextAnnotation = tmi.getAnnotations()[i];
                if (nextAnnotation != null && nextAnnotation instanceof XmlList) {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Return true if the Types are equal. Accounts for Classes and
     * Parameterized types or any combintation of the two.
     */
    private static boolean areTypesEqual(java.lang.reflect.Type type, java.lang.reflect.Type type2) {
        // handle null
        if (type == null) {
            return type2 == null;
        } else if (type instanceof Class) {
            if (type2 instanceof ParameterizedType) {

                java.lang.reflect.Type rawType = ((ParameterizedType) type2).getRawType();
                if (!areTypesEqual(type, rawType)) {
                    return false;
                }

                java.lang.reflect.Type[] args = ((ParameterizedType) type2).getActualTypeArguments();
                for (int i = 0; i < args.length; i++) {
                    Type argType = getActualArgumentType(args[i]);
                    if (!areTypesEqual(Object.class, argType)) {
                        return false;
                    }
                }
                return true;
            } else if (type2 instanceof Class) {
                return type.equals(type2);
            } else {
                return false;
            }
        } else if (type instanceof ParameterizedType) {
            if (type2 instanceof Class) {

                java.lang.reflect.Type rawType = ((ParameterizedType) type).getRawType();
                if (!areTypesEqual(type2, rawType)) {
                    return false;
                }

                java.lang.reflect.Type[] args = ((ParameterizedType) type).getActualTypeArguments();
                for (int i = 0; i < args.length; i++) {
                    Type argType = getActualArgumentType(args[i]);
                    if (!areTypesEqual(Object.class, argType)) {
                        return false;
                    }
                }
                return true;
            } else if (type2 instanceof ParameterizedType) {
                // compare raw type
                if (!areTypesEqual(((ParameterizedType) type).getRawType(),
                        ((ParameterizedType) type2).getRawType())) {
                    return false;
                }

                java.lang.reflect.Type[] ta1 = ((ParameterizedType) type).getActualTypeArguments();
                java.lang.reflect.Type[] ta2 = ((ParameterizedType) type2).getActualTypeArguments();
                // check array length
                if (ta1.length != ta2.length) {
                    return false;
                }
                for (int i = 0; i < ta1.length; i++) {
                    Type componentType1 = getActualArgumentType(ta1[i]);
                    Type componentType2 = getActualArgumentType(ta2[i]);
                    if (!areTypesEqual(componentType1, componentType2)) {
                        return false;
                    }
                }
                return true;
            } else {
                return false;
            }
        }
        return false;
    }

    private static Type getActualArgumentType(Type argument){
        if(argument instanceof WildcardType){
            Type[] upperBounds = ((WildcardType)argument).getUpperBounds();
            if(upperBounds != null && upperBounds.length >0){
                return upperBounds[0];
            }else{
                return Object.class;
            }
        }else if (argument instanceof GenericArrayType){
            return ((GenericArrayType)argument).getGenericComponentType();
        }
        return argument;
    }

    /**
     * Convenience method for creating an XmlElement object based on a given
     * Element. The method will load the eclipselink metadata model and
     * unmarshal the Element. This assumes that the Element represents an
     * xml-element to be unmarshalled.
     *
     * @param xmlElementNode
     * @param classLoader
     * @return
     */
    static org.eclipse.persistence.jaxb.xmlmodel.XmlElement getXmlElement(org.w3c.dom.Element xmlElementNode, ClassLoader classLoader) {
        try {
            Unmarshaller unmarshaller = CompilerHelper.getXmlBindingsModelContext().createUnmarshaller();
            JAXBElement<org.eclipse.persistence.jaxb.xmlmodel.XmlElement> jelt = unmarshaller.unmarshal(xmlElementNode, org.eclipse.persistence.jaxb.xmlmodel.XmlElement.class);
            return jelt.getValue();
        } catch (jakarta.xml.bind.JAXBException jaxbEx) {
            throw org.eclipse.persistence.exceptions.JAXBException.couldNotUnmarshalMetadata(jaxbEx);
        }
    }

    /**
     * If adapter class is null return null If there is a marshal method that
     * returns something other than Object on the adapter class return the
     * return type of that method Otherwise return Object.class
     */
    static Class getTypeFromAdapterClass(Class adapterClass) {
        if (adapterClass != null) {
            Class<Object> declJavaType = Object.class;
            // look for marshal method
            Method[] tacMethods = PrivilegedAccessHelper.getMethods(adapterClass);
            for (int i = 0; i < tacMethods.length; i++) {
                Method method = tacMethods[i];
                if (method.getName().equals("marshal")) {
                    Class<Object> returnType = PrivilegedAccessHelper.getMethodReturnType(method);
                    if (!(returnType == declJavaType)) {
                        declJavaType = returnType;
                        return declJavaType;
                    }
                }
            }
            return declJavaType;
        }
        return null;

    }

    /**
     * If adapter class is null return null If there is a marshal method that
     * returns something other than Object on the adapter class return the
     * return type of that method Otherwise return Object.class
     */
    public static JavaClass getTypeFromAdapterClass(JavaClass adapterClass, Helper helper) {
        if (adapterClass != null) {
            //JavaClass declJavaType = Object.class;
            JavaClass declJavaType = helper.getJavaClass(Object.class);
            // look for marshal method
            Object[] tacMethods = adapterClass.getMethods().toArray();
            for (int i = 0; i < tacMethods.length; i++) {
                JavaMethod method = (JavaMethod)tacMethods[i];
                if (method.getName().equals("marshal")) {
                    JavaClass returnType = method.getReturnType();
                    if (!(returnType.getQualifiedName().equals(declJavaType.getQualifiedName()))) {
                        declJavaType = returnType;
                        return declJavaType;
                    }
                }
            }
            return declJavaType;
        }
        return null;

    }

    /**
     * Return true if the type is a Collection, List or Set
     */
    private static boolean isCollectionType(Type theType) {
        if (theType instanceof Class) {
            if (Collection.class.isAssignableFrom((Class) theType)
                    || List.class.isAssignableFrom((Class) theType)
                    || Set.class.isAssignableFrom((Class) theType)) {
                return true;
            }
            return false;
        } else if (theType instanceof ParameterizedType) {
            Type rawType = ((ParameterizedType) theType).getRawType();
            return isCollectionType(rawType);
        }
        return false;
    }

    /**
     * The actual type accounts for adapter classes or xmlelemnt types specified
     * in either an annotation or an XML override
     *
     */
    static Type getActualType(TypeMappingInfo tmi, org.eclipse.persistence.jaxb.xmlmodel.XmlElement element) {
        try {
            if (element == null) {
                if (tmi.getAnnotations() != null) {
                    for (int i = 0; i < tmi.getAnnotations().length; i++) {
                        java.lang.annotation.Annotation nextAnnotation = tmi.getAnnotations()[i];
                        if (nextAnnotation != null) {
                            if (nextAnnotation instanceof XmlJavaTypeAdapter) {
                                Class typeClass = ((XmlJavaTypeAdapter) nextAnnotation).type();
                                if (typeClass.getName().equals("jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter$DEFAULT")) {
                                    Class<? extends XmlAdapter> adapterClass = ((XmlJavaTypeAdapter) nextAnnotation).value();
                                    return getTypeFromAdapterClass(adapterClass);
                                }
                                return typeClass;
                            } else if (nextAnnotation instanceof XmlElement) {
                                Class typeClass = ((XmlElement) nextAnnotation).type();
                                if (!typeClass.getName().equals("jakarta.xml.bind.annotation.XmlElement.DEFAULT")) {
                                    final Type tmiType = tmi.getType();
                                    if (isCollectionType(tmiType)) {
                                        final Class itemType = typeClass;
                                        Type parameterizedType = new ParameterizedType() {
                                            Type[] typeArgs = { itemType };

                                            @Override
                                            public Type[] getActualTypeArguments() {
                                                return typeArgs;
                                            }

                                            @Override
                                            public Type getOwnerType() {
                                                return null;
                                            }

                                            @Override
                                            public Type getRawType() {
                                                return tmiType;
                                            }
                                        };
                                        return parameterizedType;
                                    } else {
                                        return typeClass;
                                    }
                                }
                            }
                        }

                    }
                }
                return tmi.getType();
            } else {

                // if it has an XMLElement specified
                // Check for an adapater, then check for XMLElement.type
                if (element.getXmlJavaTypeAdapter() != null) {
                    String actualType = element.getXmlJavaTypeAdapter().getType();
                    if (actualType != null && !actualType.equals("jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter.DEFAULT")) {
                        return PrivilegedAccessHelper.getClassForName(actualType);
                    } else {
                        String adapterClassName = element.getXmlJavaTypeAdapter().getValue();
                        Class<Object> adapterClass = PrivilegedAccessHelper.getClassForName(adapterClassName);
                        return getTypeFromAdapterClass(adapterClass);
                    }
                }

                if (!(element.getType().equals("jakarta.xml.bind.annotation.XmlElement.DEFAULT"))) {
                    String actualType = element.getType();

                    final Type tmiType = tmi.getType();
                    if (isCollectionType(tmiType)) {
                        final Class<Object> itemType = PrivilegedAccessHelper.getClassForName(actualType);
                        Type parameterizedType = new ParameterizedType() {
                            Type[] typeArgs = { itemType };

                            @Override
                            public Type[] getActualTypeArguments() {
                                return typeArgs;
                            }

                            @Override
                            public Type getOwnerType() {
                                return null;
                            }

                            @Override
                            public Type getRawType() {
                                return tmiType;
                            }
                        };
                        return parameterizedType;
                    } else {
                        return PrivilegedAccessHelper.getClassForName(actualType);
                    }
                }
                return tmi.getType();
            }
        } catch (Exception e) {
            return tmi.getType();
        }
    }

    /**
     * The method will load the eclipselink metadata model and return the
     * corresponding JAXBContext
     */
    public static JAXBContext getXmlBindingsModelContext() {
        if (xmlBindingsModelContext == null) {
            try {
                xmlBindingsModelContext = (JAXBContext) JAXBContextFactory.createContext(METADATA_MODEL_PACKAGE,CompilerHelper.class.getClassLoader());
            } catch (JAXBException e) {
                throw org.eclipse.persistence.exceptions.JAXBException.couldNotCreateContextForXmlModel(e);
            }
            if (xmlBindingsModelContext == null) {
                throw org.eclipse.persistence.exceptions.JAXBException.couldNotCreateContextForXmlModel();
            }
        }
        return xmlBindingsModelContext;
    }

    public static JavaClass getNextMappedSuperClass(JavaClass cls, Map<String, TypeInfo> typeInfo, Helper helper) {
        JavaClass superClass = cls.getSuperclass();

        if(superClass == null || helper.isBuiltInJavaType(cls) || superClass.getRawName().equals("java.lang.Object")){
            return null;
        }
        TypeInfo parentTypeInfo = typeInfo.get(superClass.getQualifiedName());
        if(parentTypeInfo == null || parentTypeInfo.isTransient()) {
            return getNextMappedSuperClass(superClass, typeInfo, helper);
        }

        return superClass;
    }

    public static void addClassToClassLoader(JavaClass cls, ClassLoader loader) {

        if(loader.getClass() == JaxbClassLoader.class && cls.getClass() == JavaClassImpl.class) {
            Class wrappedClass = ((JavaClassImpl)cls).getJavaClass();
            ((JaxbClassLoader)loader).putClass(wrappedClass.getName(), wrappedClass);
        }
    }

    static boolean hasNonAttributeJoinNodes(Property property) {
        if(property.isSetXmlJoinNodes()) {
            for(XmlJoinNodes.XmlJoinNode next: property.getXmlJoinNodes().getXmlJoinNode()) {
                if(!(next.getXmlPath().startsWith("@"))) {
                    return true;
                }
            }
        } else if(property.isSetXmlJoinNodesList()) {
            for(XmlJoinNodes nextNodes:property.getXmlJoinNodesList()) {
                for(XmlJoinNodes.XmlJoinNode next: nextNodes.getXmlJoinNode()) {
                    if(!(next.getXmlPath().startsWith("@"))) {
                        return true;
                    }
                }
            }

        }
        return false;
    }

    public static Object createAccessorFor(JavaClass jClass, Property property, Helper helper, AccessorFactoryWrapper accessorFactory) {
        if(!(jClass.getClass() == JavaClassImpl.class)) {
            return null;
        }
        Class beanClass = ((JavaClassImpl)jClass).getJavaClass();
        if(property.isMethodProperty()) {
            try {
                Method getMethod = null;
                Method setMethod = null;
                if(property.getGetMethodName() != null) {
                    getMethod = PrivilegedAccessHelper.getMethod(beanClass, property.getGetMethodName(), new Class[]{}, true);
                }
                if(property.getSetMethodName() != null) {
                    String setMethodParamTypeName = property.getType().getName();
                    JavaClassImpl paramType = (JavaClassImpl)helper.getJavaClass(setMethodParamTypeName);
                    Class[] setMethodParams = new Class[]{paramType.getJavaClass()};
                    setMethod = PrivilegedAccessHelper.getMethod(beanClass, property.getSetMethodName(), setMethodParams, true);
                }
                return accessorFactory.createPropertyAccessor(beanClass, getMethod, setMethod);
            } catch(Exception ex) {}
        }  else {
            try {
                Field field = PrivilegedAccessHelper.getField(beanClass, ((JavaField)property.getElement()).getName(), true);
                return accessorFactory.createFieldAccessor(beanClass, field, property.isReadOnly());
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    public static boolean isSimpleType(TypeInfo info) {
        if (info.isEnumerationType()) {
            return true;
        }
        Property xmlValueProperty = info.getXmlValueProperty();

        boolean hasMappedAttributes = false;

        for (Property nextProp : info.getPropertyList()) {
            if (nextProp.isAttribute() && !nextProp.isTransient()) {
                hasMappedAttributes = true;
            }
        }
        hasMappedAttributes = hasMappedAttributes || info.hasPredicateProperties();

        return (xmlValueProperty != null && !hasMappedAttributes);
    }

}
