/*
 * 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.description.builder;

import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.namespace.QName;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

/**
 * 
 */
class DescriptionBuilderUtils {

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

    static String JAXWS_HOLDER_CLASS = "javax.xml.ws.Holder";

    private static final String INT_PRIMITIVE = "int";
    private static final String INT_PRIMITIVE_ENCODING = "I";
    private static final String BYTE_PRIMITIVE = "byte";
    private static final String BYTE_PRIMITIVE_ENCODING = "B";
    private static final String CHAR_PRIMITIVE = "char";
    private static final String CHAR_PRIMITIVE_ENCODING = "C";
    private static final String SHORT_PRIMITIVE = "short";
    private static final String SHORT_PRIMITIVE_ENCODING = "S";
    private static final String BOOLEAN_PRIMITIVE = "boolean";
    private static final String BOOLEAN_PRIMITIVE_ENCODING = "Z";
    private static final String LONG_PRIMITIVE = "long";
    private static final String LONG_PRIMITIVE_ENCODING = "J";
    private static final String FLOAT_PRIMITIVE = "float";
    private static final String FLOAT_PRIMITIVE_ENCODING = "F";
    private static final String DOUBLE_PRIMITIVE = "double";
    private static final String DOUBLE_PRIMITIVE_ENCODING = "D";
    private static final String VOID_PRIMITIVE = "void";
    // REVIEW: This may not be the correct encoding for Void
    private static final String VOID_PRIMITIVE_ENCODING = "V";

    /**
     * Returns a string representing the outermost generic raw type class, or null if the argument
     * is not a generic.  For example if the string "javax.xml.ws.Holder<my.package.MyObject>" is
     * passed in, the string "javax.xml.ws.Holder" will be returned.
     * <p/>
     * Note that generic arrays are supported.  For example, for "Holder<List<String>[][]", the
     * returned value will be "List[][]".
     *
     * @param inputType
     * @return A string representing the generic raw type or null if there is no generic.
     */
    static String getRawType(String inputType) {
        String returnRawType = null;
        int leftBracket = inputType.indexOf("<");
        int rightBracket = inputType.lastIndexOf(">");
        if (leftBracket > 0 && rightBracket > 0 && rightBracket > leftBracket) {
            String part1 = inputType.substring(0, leftBracket);
            if ((rightBracket + 1) == inputType.length()) {
                // There is nothing after the closing ">" we need to append to the raw type
                returnRawType = part1;
            } else {
                // Skip over the closing ">" then append the rest of the string to the raw type
                // This would be an array declaration for example.
                String part2 = inputType.substring(rightBracket + 1).trim();
                returnRawType = part1 + part2;
            }
        }
        return returnRawType;
    }

    /**
     * Return the actual type in a JAX-WS holder declaration.  For example, for the argument
     * "javax.xml.ws.Holder<my.package.MyObject>", return "my.package.MyObject". If the actual type
     * itself is a generic, then that raw type will be returned.  For example,
     * "javax.xml.ws.Holder<java.util.List<my.package.MyObject>>" will return "java.util.List".
     * <p/>
     * Note that Holders of Arrays and of Generic Arrays are also supported.  For example, for
     * "javax.xml.ws.Holder<String[]>", return "String[]".  For an array of a generic, the array of
     * the raw type is returned.  For example, for "javax.xml.ws.Holder<List<String>[][]>", return
     * "List[][]".
     * <p/>
     * Important note!  The JAX-WS Holder generic only supports a single actual type, i.e. the
     * generic is javax.xml.ws.Holder<T>.  This method is not general purpose; it does not support
     * generics with multiple types such as Generic<K,V> at the outermost level.
     *
     * @param holderInputString
     * @return return the actual argument class name for a JAX-WS Holder; returns null if the
     *         argument is not a JAX-WS Holder
     */
    static String getHolderActualType(String holderInputString) {
        String returnString = null;
        if (DescriptionBuilderUtils.isHolderType(holderInputString)) {
            int leftBracket = holderInputString.indexOf("<");
            int rightBracket = holderInputString.lastIndexOf(">");
            if (leftBracket > 0 && rightBracket > leftBracket + 1) {
                // Get everything between the outermost "<" and ">"
                String actualType =
                        holderInputString.substring(leftBracket + 1, rightBracket).trim();
                // If the holder contained a generic, then get the generic raw type (e.g. "List" for
                // Holder<List<String>>).
                String rawType = getRawType(actualType);
                if (rawType != null) {
                    returnString = rawType;
                } else {
                    return returnString = actualType;
                }
            }
        }
        return returnString;
    }


    /**
     * Check if the input String is a JAX-WS Holder.  For example "javax.xml.ws.Holder<my.package.MyObject>".
     *
     * @param checkType
     * @return true if it is a JAX-WS Holder type; false otherwise.
     */
    static boolean isHolderType(String checkType) {
        boolean isHolder = false;
        if (checkType != null) {
            if (checkType.startsWith(JAXWS_HOLDER_CLASS)) {
                isHolder = checkType.length() == JAXWS_HOLDER_CLASS.length() ||
                           checkType.charAt(JAXWS_HOLDER_CLASS.length()) == '<';
            }
        }
        return isHolder;
    }

    /**
     * Answers if the String representing the class contains an array declaration. For example
     * "Foo[][]" would return true, as would "int[]".
     *
     * @param className
     * @return
     */
    static boolean isClassAnArray(String className) {
        if (className != null && className.indexOf("[") > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * For an class name that is an array, return the non-array declaration portion. For example
     * "my.package.Foo[][]" would return "my.package.Foo". Returns null if the argument does not
     * contain an array declaration.
     *
     * @param fullClassName
     * @return
     */
    static String getBaseArrayClassName(String fullClassName) {
        String baseArrayClassName = null;
        if (fullClassName != null) {
            int firstArrayDimension = fullClassName.indexOf("[");
            if (firstArrayDimension > 0) {
                baseArrayClassName = fullClassName.substring(0, firstArrayDimension);
            }
        }
        return baseArrayClassName;
    }

    /**
     * Return a prefix suitable for passing to Class.forName(String) for an array.  Each array
     * dimension represented by "[]" will be represented by a single "[".
     *
     * @param arrayClassName
     * @return
     */
    static String getArrayDimensionPrefix(String arrayClassName) {
        StringBuffer arrayDimPrefix = new StringBuffer();

        if (arrayClassName != null) {
            int arrayDimIndex = arrayClassName.indexOf("[]");
            while (arrayDimIndex > 0) {
                arrayDimPrefix.append("[");
                // Skip over this "[]" and see if there are any more.
                int startNext = arrayDimIndex + 2;
                arrayDimIndex = arrayClassName.indexOf("[]", startNext);
            }
        }

        if (arrayDimPrefix.length() > 0)
            return arrayDimPrefix.toString();
        else
            return null;
    }

    /**
     * For primitives, return the appropriate primitive class.  Note that arrays of primitives are
     * handled differently, like arrays of objects.  Only non-array primitives are processed by this
     * method.  This method understands both the typical primitive declaration (e.g. "int") and the
     * encoding used as for arrays (e.g. "I").
     *
     * @param classType
     * @return
     */
    static Class getPrimitiveClass(String classType) {

        Class paramClass = null;

        if (INT_PRIMITIVE.equals(classType) || INT_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = int.class;
        } else if (BYTE_PRIMITIVE.equals(classType) || BYTE_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = byte.class;
        } else if (CHAR_PRIMITIVE.equals(classType) || CHAR_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = char.class;
        } else
        if (SHORT_PRIMITIVE.equals(classType) || SHORT_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = short.class;
        } else
        if (BOOLEAN_PRIMITIVE.equals(classType) || BOOLEAN_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = boolean.class;
        } else if (LONG_PRIMITIVE.equals(classType) || LONG_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = long.class;
        } else
        if (FLOAT_PRIMITIVE.equals(classType) || FLOAT_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = float.class;
        } else
        if (DOUBLE_PRIMITIVE.equals(classType) || DOUBLE_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = double.class;
        } else if (VOID_PRIMITIVE.equals(classType) || VOID_PRIMITIVE_ENCODING.equals(classType)) {
            paramClass = void.class;
        }
        return paramClass;
    }

    /**
     * Returns the encoding used to represent a Class for an array of a primitive type.  For
     * example, an array of boolean is represented by "Z". This is as described in the javadoc for
     * Class.getName().  If the argument is not a primitive type, a null will be returned.
     * <p/>
     * Note that arrays of voids are not allowed; a null will be returned.
     *
     * @param primitiveType
     * @return
     */
    static String getPrimitiveTypeArrayEncoding(String primitiveType) {
        String encoding = null;

        if (BOOLEAN_PRIMITIVE.equals(primitiveType)) {
            encoding = BOOLEAN_PRIMITIVE_ENCODING;
        } else if (BYTE_PRIMITIVE.equals(primitiveType)) {
            encoding = BYTE_PRIMITIVE_ENCODING;
        } else if (CHAR_PRIMITIVE.equals(primitiveType)) {
            encoding = CHAR_PRIMITIVE_ENCODING;
        } else if (DOUBLE_PRIMITIVE.equals(primitiveType)) {
            encoding = DOUBLE_PRIMITIVE_ENCODING;
        } else if (FLOAT_PRIMITIVE.equals(primitiveType)) {
            encoding = FLOAT_PRIMITIVE_ENCODING;
        } else if (INT_PRIMITIVE.equals(primitiveType)) {
            encoding = INT_PRIMITIVE_ENCODING;
        } else if (LONG_PRIMITIVE.equals(primitiveType)) {
            encoding = LONG_PRIMITIVE_ENCODING;
        } else if (SHORT_PRIMITIVE.equals(primitiveType)) {
            encoding = SHORT_PRIMITIVE_ENCODING;
        }
        return encoding;
    }

    /**
     * If the parameter represents and array, then the returned string is in a format that a
     * Class.forName(String) can be done on it.  This format is described by Class.getName(). If the
     * parameter does not represent an array, the parememter is returned unmodified.
     * <p/>
     * Note that arrays of primitives are processed as well as arrays of objects.
     *
     * @param classToLoad
     * @return
     */
    static String reparseIfArray(String classToLoad) {

        String reparsedClassName = classToLoad;
        if (isClassAnArray(classToLoad)) {
            String baseType = getBaseArrayClassName(classToLoad);
            String dimensionPrefix = getArrayDimensionPrefix(classToLoad);
            if (getPrimitiveTypeArrayEncoding(baseType) != null) {
                reparsedClassName = dimensionPrefix + getPrimitiveTypeArrayEncoding(baseType);
            } else {
                reparsedClassName = dimensionPrefix + "L" + baseType + ";";
            }
        }
        return reparsedClassName;
    }

    /**
     * Load a class represented in a Description Builder Composite.  If a classloader is specified,
     * it will be used; otherwise the default classloader is used.
     *
     * @param classToLoad
     * @param classLoader
     * @return
     */
    static Class loadClassFromComposite(String classToLoad, ClassLoader classLoader) {
        Class returnClass = null;

        // If this is an array, then create a string version as described by Class.getName.
        // For example, "Foo[][]" becomes "[[LFoo".  Note that arrays of primitives must also be parsed.
        classToLoad = DescriptionBuilderUtils.reparseIfArray(classToLoad);

        if (classLoader != null) {
            // Use the specified classloader to load the class.
            try {
                returnClass = forName(classToLoad, false, classLoader);
            }
            //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that
            //does not extend Exception, so lets catch everything that extends Throwable
            //rather than just Exception.
            catch (Throwable ex) {
                throw ExceptionFactory.makeWebServiceException(
                        Messages.getMessage("DBUClassNotFound", classToLoad, classLoader.toString()));
            }
        } else {
            //Use the thread context class loader to load the class.
            try {
                returnClass = forName(classToLoad, false,
                                                       getContextClassLoader(null));
            }
            catch (Throwable ex) {
                //Use the default classloader to load the class.
                try {
                    returnClass = forName(classToLoad);
                }
                //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that
                //does not extend Exception
                catch (Throwable ex2) {
                    throw ExceptionFactory.makeWebServiceException(
                            Messages.getMessage("DBUClassNotFound2", classToLoad));
                }
            }
        }
        return returnClass;
    }

    static boolean isEmpty(String string) {
        return (string == null || "".equals(string));
    }

    static boolean isEmpty(QName qname) {
        return qname == null || isEmpty(qname.getLocalPart());
    }

    /**
     * Return the class for this name
     *
     * @return Class
     */
    private static Class forName(final String className, final boolean initialize,
                                final ClassLoader classloader) throws ClassNotFoundException {
        Class cl = null;
        try {
            cl = (Class) AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Object run() throws ClassNotFoundException {
                            return Class.forName(className, initialize, classloader);
                        }
                    }
            );
        } catch (PrivilegedActionException e) {
            if (log.isDebugEnabled()) {
                log.debug("Exception thrown from AccessController: " + e.getMessage(), e);
            }
            throw (ClassNotFoundException) e.getException();
        }

        return cl;
    }

    /**
     * Return the class for this name
     *
     * @return Class
     */
    private static Class forName(final String className) throws ClassNotFoundException {
        Class cl = null;
        try {
            cl = (Class) AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Object run() throws ClassNotFoundException {
                            return Class.forName(className);
                        }
                    }
            );
        } catch (PrivilegedActionException e) {
            if (log.isDebugEnabled()) {
                log.debug("Exception thrown from AccessController: " + e.getMessage(), e);
            }
            throw (ClassNotFoundException) e.getException();
        }

        return cl;
    }

    /**
     * @return ClassLoader
     */
    private static ClassLoader getContextClassLoader(final ClassLoader classLoader) {
        ClassLoader cl;
        try {
            cl = (ClassLoader) AccessController.doPrivileged(
                    new PrivilegedExceptionAction() {
                        public Object run() throws ClassNotFoundException {
                            return classLoader != null ? classLoader : Thread.currentThread().getContextClassLoader();
                        }
                    }
            );
        } catch (PrivilegedActionException e) {
            if (log.isDebugEnabled()) {
                log.debug("Exception thrown from AccessController: " + e.getMessage(), e);
            }
            throw ExceptionFactory.makeWebServiceException(e.getException());
        }

        return cl;
    }
}
