/*
 * 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:
//     Rick Barkhouse - 2.1 - Initial implementation
package org.eclipse.persistence.jaxb.javamodel.xjc;

import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.jaxb.javamodel.JavaAnnotation;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaMethod;

import com.sun.codemodel.JAnnotationUse;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JClassAlreadyExistsException;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JMethod;
import com.sun.codemodel.JType;

/**
 * INTERNAL:
 * <p>
 * <b>Purpose:</b> <code>JavaMethod</code> implementation wrapping XJC's <code>JMethod</code>.  Used when
 * bootstrapping a <code>DynamicJAXBContext</code> from an XML Schema.
 * </p>
 *
 * <p>
 * <b>Responsibilities:</b>
 * </p>
 * <ul>
 *    <li>Provide <code>Method</code> information from the underlying <code>JMethod</code>.</li>
 * </ul>
 *
 * @since EclipseLink 2.1
 *
 * @see org.eclipse.persistence.jaxb.javamodel.JavaMethod
 */
public class XJCJavaMethodImpl implements JavaMethod {

    private JMethod xjcMethod;
    private JCodeModel jCodeModel;
    private DynamicClassLoader dynamicClassLoader;
    private JavaClass owningClass;

    /**
     * Construct a new instance of <code>XJCJavaMethodImpl</code>.
     *
     * @param javaMethod - the XJC <code>JMethod</code> to be wrapped.
     * @param codeModel - the XJC <code>JCodeModel</code> this method belongs to.
     * @param loader - the <code>ClassLoader</code> used to bootstrap the <code>DynamicJAXBContext</code>.
     * @param owner - the <code>JavaClass</code> this method belongs to.
     */
    public XJCJavaMethodImpl(JMethod javaMethod, JCodeModel codeModel, DynamicClassLoader loader, JavaClass owner) {
        this.xjcMethod = javaMethod;
        this.jCodeModel = codeModel;
        this.dynamicClassLoader = loader;
        this.owningClass = owner;
    }

    /**
     * If this <code>JavaMethod</code> is annotated with an <code>Annotation</code> matching <code>aClass</code>,
     * return its <code>JavaAnnotation</code> representation.
     *
     * @param aClass a <code>JavaClass</code> representing the <code>Annotation</code> to look for.
     *
     * @return the <code>JavaAnnotation</code> represented by <code>aClass</code>, if one exists, otherwise return <code>null</code>.
     */
    @Override
    @SuppressWarnings("unchecked")
    public JavaAnnotation getAnnotation(JavaClass aClass) {
        if (aClass != null) {
            Collection<JAnnotationUse> annotations = xjcMethod.annotations();
            for (JAnnotationUse annotationUse : annotations) {
                XJCJavaAnnotationImpl xjcAnnotation = new XJCJavaAnnotationImpl(annotationUse, dynamicClassLoader);
                if (xjcAnnotation.getJavaAnnotationClass().getCanonicalName().equals(aClass.getQualifiedName())) {
                    return xjcAnnotation;
                }
            }
            // Didn't find annotation so return null
            return null;
        }
        // aClass was null so return null
        return null;
    }

    /**
     * Return all of the <code>Annotations</code> for this <code>JavaMethod</code>.
     *
     * @return A <code>Collection</code> containing this <code>JavaMethod's</code> <code>JavaAnnotations</code>.
     */
    @Override
    @SuppressWarnings("unchecked")
    public Collection<JavaAnnotation> getAnnotations() {
        ArrayList<JavaAnnotation> annotationsList = new ArrayList<>();
        Collection<JAnnotationUse> annotations = xjcMethod.annotations();
        for (JAnnotationUse annotationUse : annotations) {
            XJCJavaAnnotationImpl xjcAnnotation = new XJCJavaAnnotationImpl(annotationUse, dynamicClassLoader);
            annotationsList.add(xjcAnnotation);
        }
        return annotationsList;
    }

    /**
     * Returns the name of this <code>JavaMethod</code>.
     *
     * @return the <code>String</code> name of this <code>JavaMethod</code>.
     */
    @Override
    public String getName() {
        return xjcMethod.name();
    }

    /**
     * Returns the array of parameters for this <code>JavaMethod</code>.
     *
     * @return a <code>JavaClass[]</code> representing the argument types for this method.
     */
    @Override
    public JavaClass[] getParameterTypes() {
        JType[] params = xjcMethod.listParamTypes();
        JavaClass[] paramArray = new JavaClass[params.length];

        for (int i = 0; i < params.length; i++) {
            if (((XJCJavaClassImpl) getOwningClass()).getJavaModel() != null) {
                paramArray[i] = ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(params[i].fullName());
            } else {
                paramArray[i] = new XJCJavaClassImpl((JDefinedClass) params[i], jCodeModel, dynamicClassLoader);
            }
        }
        return paramArray;
    }

    /**
     * Returns this <code>JavaMethod's</code> return type.
     *
     * @return a <code>JavaClass</code> representing the return type of this method.
     */
    public JavaClass getResolvedType() {
        if (((XJCJavaClassImpl) getOwningClass()).getJavaModel() != null) {
            return ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(xjcMethod.type().fullName());
        }

        try {
            return new XJCJavaClassImpl(jCodeModel._class(xjcMethod.type().fullName()), jCodeModel, dynamicClassLoader);
        } catch (JClassAlreadyExistsException ex) {
            return new XJCJavaClassImpl(jCodeModel._getClass(xjcMethod.type().fullName()), jCodeModel, dynamicClassLoader);
        }
    }

    /**
     * Returns this <code>JavaMethod's</code> return type.
     *
     * @return a <code>JavaClass</code> representing the return type of this method.
     */
    @Override
    @SuppressWarnings("unchecked")
    public JavaClass getReturnType() {
        JType type = xjcMethod.type();
        JavaClass returnClass = null;

        if (((XJCJavaClassImpl) getOwningClass()).getJavaModel() != null) {
            returnClass = ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(type.fullName());
        } else {
            try {
                returnClass = new XJCJavaClassImpl(jCodeModel._class(type.fullName()), jCodeModel, dynamicClassLoader);
            } catch (JClassAlreadyExistsException ex) {
                returnClass = new XJCJavaClassImpl(jCodeModel._getClass(type.fullName()), jCodeModel, dynamicClassLoader);
            }
        }
        if (type instanceof JClass) {
            JClass jcl = (JClass) type;
            if (jcl.isParameterized()) {
                List<JClass> args = jcl.getTypeParameters();
                JClass arg = args.get(0);
                JavaClass argClass = ((XJCJavaClassImpl) getOwningClass()).getJavaModel().getClass(arg.fullName());
                ((XJCJavaClassImpl) returnClass).setActualTypeArgument(argClass);
            }
        }
        return returnClass;
    }

    /**
     * Indicates if this <code>JavaMethod</code> has actual type arguments, i.e. is a
     * parameterized type (for example, <code>List&lt;Employee</code>).
     *
     * @return <code>true</code> if this <code>JavaClass</code> is parameterized, otherwise <code>false</code>.
     */
    public boolean hasActualTypeArguments() {
        try {
            JavaClass[] allParams = getParameterTypes();

            for (JavaClass type : allParams) {
                Class<?> paramClass = Class.forName(type.getPackageName() + "." + type.getName());
                if (paramClass.getConstructor().newInstance() instanceof ParameterizedType) {
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Not supported.
     */
    public Collection<Object> getActualTypeArguments() {
        throw new UnsupportedOperationException("getActualTypeArguments");
    }

    /**
     * Returns the Java language modifiers for this <code>JavaMethod</code>, encoded in an integer.
     *
     * @return the <code>int</code> representing the modifiers for this method.
     *
     * @see java.lang.reflect.Modifier
     */
    @Override
    public int getModifiers() {
        return xjcMethod.mods().getValue();
    }

    /**
     * Indicates if this <code>JavaMethod</code> is <code>abstract</code>.
     *
     * @return <code>true</code> if this <code>JavaMethod</code> is <code>abstract</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isAbstract() {
        return Modifier.isAbstract(getModifiers());
    }

    /**
     * Indicates if this <code>JavaMethod</code> is <code>private</code>.
     *
     * @return <code>true</code> if this <code>JavaMethod</code> is <code>private</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isPrivate() {
        return Modifier.isPrivate(getModifiers());
    }

    /**
     * Indicates if this <code>JavaMethod</code> is <code>protected</code>.
     *
     * @return <code>true</code> if this <code>JavaMethod</code> is <code>protected</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isProtected() {
        return Modifier.isProtected(getModifiers());
    }

    /**
     * Indicates if this <code>JavaMethod</code> is <code>public</code>.
     *
     * @return <code>true</code> if this <code>JavaMethod</code> is <code>public</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isPublic() {
        return Modifier.isPublic(getModifiers());
    }

    /**
     * Indicates if this <code>JavaMethod</code> is <code>static</code>.
     *
     * @return <code>true</code> if this <code>JavaMethod</code> is <code>static</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isStatic() {
        return Modifier.isStatic(getModifiers());
    }

    /**
     * Indicates if this <code>JavaMethod</code> is <code>final</code>.
     *
     * @return <code>true</code> if this <code>JavaMethod</code> is <code>final</code>, otherwise <code>false</code>.
     */
    @Override
    public boolean isFinal() {
        return Modifier.isFinal(getModifiers());
    }

    /**
     * Not supported.
     */
    @Override
    public boolean isSynthetic() {
        return false;
    }

    /**
     * Not supported.
     */
    @Override
    public JavaAnnotation getDeclaredAnnotation(JavaClass arg0) {
        throw new UnsupportedOperationException("getDeclaredAnnotation");
    }

    /**
     * Not supported.
     */
    @Override
    public Collection<JavaAnnotation> getDeclaredAnnotations() {
        throw new UnsupportedOperationException("getDeclaredAnnotations");
    }

    /**
     * Returns the <code>JavaClass</code> which contains this method.
     *
     * @return <code>JavaClass</code> representing the owner of this <code>JavaMethod</code>.
     */
    @Override
    public JavaClass getOwningClass() {
        return owningClass;
    }

    /**
     * Set the <code>JavaClass</code> which contains this method.
     *
     * @param owningClass the <code>JavaClass</code> representing the owner of this <code>JavaMethod</code>.
     */
    public void setOwningClass(JavaClass owningClass) {
        this.owningClass = owningClass;
    }

    /**
     * Not supported.
     */
    @Override
    public boolean isBridge() {
        return false;
    }
}
