/*
 * Copyright (c) 1998, 2020 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.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 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 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 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 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 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);
    }

}
