/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.axis2.jaxws.utility;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import javax.jws.WebService;
import javax.xml.ws.Holder;
import javax.xml.ws.Service;
import javax.xml.ws.WebFault;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceProvider;

import org.apache.axis2.java.security.AccessController;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/** Contains static Class utility methods related to method parameter/argument marshalling. */
public class ClassUtils {

    private static Log log = LogFactory.getLog(ClassUtils.class);


    /**
     * Gets the RootCause for an throwable. The root cause is defined as the first
     * non-InvocationTargetException.
     *
     * @param e Throwable
     * @return Throwable root cause
     */
    public static Throwable getRootCause(Throwable e) {
        Throwable t = null;

        if (e != null) {
            if (e instanceof InvocationTargetException) {
                t = ((InvocationTargetException)e).getTargetException();
            } else {
                t = null;
            }

            if (t != null) {
                e = getRootCause(t);
            }
        }
        return e;
    }

    private static HashMap loadClassMap = new HashMap();

    static {
        loadClassMap.put("byte", byte.class);
        loadClassMap.put("int", int.class);
        loadClassMap.put("short", short.class);
        loadClassMap.put("long", long.class);
        loadClassMap.put("float", float.class);
        loadClassMap.put("double", double.class);
        loadClassMap.put("boolean", boolean.class);
        loadClassMap.put("char", char.class);
        loadClassMap.put("void", void.class);
    }

    /** Converts text of the form Foo[] to the proper class name for loading [LFoo */
    private static HashMap loadableMap = new HashMap();

    static {
        loadableMap.put("byte", "B");
        loadableMap.put("char", "C");
        loadableMap.put("double", "D");
        loadableMap.put("float", "F");
        loadableMap.put("int", "I");
        loadableMap.put("long", "J");
        loadableMap.put("short", "S");
        loadableMap.put("boolean", "Z");
    }

    /**
     * @param text String
     * @return String that can be used for Class.forName
     */
    public static String getLoadableClassName(String text) {
        int bracket = text.indexOf("[");
        String className = text;

        // Get the className without any array brackets
        if (bracket > 0) {
            className = className.substring(0, bracket);
        }

        // Now get the loadable name from the map or 
        // its L<className>;
        String loadClass = (String)loadableMap.get(className);
        if (loadClass == null) {
            loadClass = "L" + className + ";";
        }

        // Now prepend [ for each array dimension
        if (bracket > 0) {
            int i = text.indexOf("]");
            while (i > 0) {
                loadClass = "[" + loadClass;
                i = text.indexOf("]", i + 1);
            }
        }
        return loadClass;
    }

    /** Converts text of the form [LFoo to the Foo[] */
    public static String getTextClassName(String text) {
        if (text == null ||
                text.indexOf("[") != 0)
            return text;
        String className = "";
        int index = 0;
        while (index < text.length() &&
                text.charAt(index) == '[') {
            index ++;
            className += "[]";
        }
        if (index < text.length()) {
            if (text.charAt(index) == 'B')
                className = "byte" + className;
            else if (text.charAt(index) == 'C')
                className = "char" + className;
            else if (text.charAt(index) == 'D')
                className = "double" + className;
            else if (text.charAt(index) == 'F')
                className = "float" + className;
            else if (text.charAt(index) == 'I')
                className = "int" + className;
            else if (text.charAt(index) == 'J')
                className = "long" + className;
            else if (text.charAt(index) == 'S')
                className = "short" + className;
            else if (text.charAt(index) == 'Z')
                className = "boolean" + className;
            else if (text.equals("void"))
                className = "void";
            else {
                className = text.substring(index + 1, text.indexOf(";")) + className;
            }
        }
        return className;
    }

    /**
     * @param primitive
     * @return java wrapper class or null
     */
    public static Class getWrapperClass(Class primitive) {
        if (primitive == int.class)
            return java.lang.Integer.class;
        else if (primitive == short.class)
            return java.lang.Short.class;
        else if (primitive == boolean.class)
            return java.lang.Boolean.class;
        else if (primitive == byte.class)
            return java.lang.Byte.class;
        else if (primitive == long.class)
            return java.lang.Long.class;
        else if (primitive == double.class)
            return java.lang.Double.class;
        else if (primitive == float.class)
            return java.lang.Float.class;
        else if (primitive == char.class)
            return java.lang.Character.class;

        return null;
    }


    /**
     * @param wrapper
     * @return primitive clas or null
     */
    public static Class getPrimitiveClass(Class wrapper) {
        if (wrapper == java.lang.Integer.class)
            return int.class;
        else if (wrapper == java.lang.Short.class)
            return short.class;
        else if (wrapper == java.lang.Boolean.class)
            return boolean.class;
        else if (wrapper == java.lang.Byte.class)
            return byte.class;
        else if (wrapper == java.lang.Long.class)
            return long.class;
        else if (wrapper == java.lang.Double.class)
            return double.class;
        else if (wrapper == java.lang.Float.class)
            return float.class;
        else if (wrapper == java.lang.Character.class)
            return char.class;

        return null;
    }

    private static final Class[] noClass = new Class[] { };

    /**
     * Get the default public constructor
     *
     * @param clazz
     * @return Constructor or null
     */
    public static Constructor getDefaultPublicConstructor(Class clazz) {
        try {
            return clazz.getConstructor(noClass);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * @param name of primitive type
     * @return primitive Class or null
     */
    public static Class getPrimitiveClass(String text) {
        return (Class)loadClassMap.get(text);
    }

    /**
     * @param cls
     * @return true if this is a JAX-WS or JAX-WS generated class
     */
    public static final boolean isJAXWSClass(Class cls) {
        // TODO Processing all of these annotations is very expensive.  We need to cache the 
        // result in a static WeakHashMap<Class, Boolean>

        // Kinds of generated classes: Service, Provider, Impl, Exception, Holder
        // Or the class is in the jaxws.xml.ws package

        // Check for Impl
        WebService wsAnn = (WebService)getAnnotation(cls,WebService.class);
        if (wsAnn != null) {
            return true;
        }

        // Check for service
        WebServiceClient wscAnn = (WebServiceClient)getAnnotation(cls,WebServiceClient.class);
        if (wscAnn != null) {
            return true;
        }

        // Check for provider
        WebServiceProvider wspAnn = (WebServiceProvider)
            getAnnotation(cls,WebServiceProvider.class);
        if (wspAnn != null) {
            return true;
        }

        // Check for Exception
        WebFault wfAnn = (WebFault)getAnnotation(cls,WebFault.class);
        if (wfAnn != null) {
            return true;
        }

        // Check for Holder
        if (Holder.class.isAssignableFrom(cls)) {
            return true;
        }

        // Check for a javax.xml.ws.Service class instance
        if (Service.class.isAssignableFrom(cls)) {
            return true;
        }

        String className = cls.getPackage() == null ? null : cls.getPackage().getName();
        if (className != null && className.startsWith("javax.xml.ws") && !className.startsWith("javax.xml.ws.wsaddressing")) {
            return true;
        }
        
        return false;
    }
    
    /**
     * Get an annotation.  This is wrappered to avoid a Java2Security violation.
     * @param cls Class that contains annotation 
     * @param annotation Class of requrested Annotation
     * @return annotation or null
     */
    private static Annotation getAnnotation(final AnnotatedElement element, final Class annotation) {
        return (Annotation) AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                return element.getAnnotation(annotation);
            }
        });
    }
    
    /**
     * 
     */
    public static Set<Class> getClasses(Type type, Set<Class> list) {
        if (list == null) {
            list = new HashSet<Class>();
        }
        try {
            if (type instanceof Class) {
                Class<?> clazz = (Class<?>)type;
                if (clazz.isArray()) {
                    getClasses(clazz.getComponentType(), list);
                } else {
                    list.add(clazz);
                }
            }
            if (type instanceof ParameterizedType) {
                ParameterizedType pt = (ParameterizedType) type;
                getClasses(pt.getRawType(), list);
                Type types[] = pt.getActualTypeArguments();
                if (types != null) {
                    for (int i=0; i<types.length; i++) {
                        getClasses(types[i], list);
                    }
                }
            } 
            if (type instanceof GenericArrayType) {
                GenericArrayType gat = (GenericArrayType) type;
                getClasses(gat.getGenericComponentType(), list);
            }
        } catch (Throwable t) {
            if (log.isDebugEnabled()) {
                log.debug("Problem occurred in getClasses. Processing continues " + t);
            }
        }
        return list;
    }
    
}

