/*
 * 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.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

import javax.xml.bind.annotation.XmlEnum;

import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Utility methods for JAXB Enum classes
 */
public class XmlEnumUtils {
    private static final Log log = LogFactory.getLog(XmlEnumUtils.class);
    /**
     * Static Utility classes have private construcors
     */
    private XmlEnumUtils() {}
    
    /**
     * @param e Class of enum 
     * @return a base type that can be used for constructing the enum
     */
    public static Class getConversionType(final Class e) {
        Class cls = null;
        if (log.isDebugEnabled()) {
            log.debug("getConversionType for " + e);
        }
        try {
            cls = (Class)     
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        // Look for forName method that is generated by JAXB.
                        Method m = fromValueMethod(e, String.class);
                        if (m != null) {
                            return String.class;
                        }
                        
                        // If we cannot find forName(String) then look for @XmlEnum value
                        // and then look for a forName with the indicated base type
                        if (log.isDebugEnabled()) {
                            log.debug("try looking for @XmlEnum ");
                        }
                        XmlEnum xmlEnum = (XmlEnum)
                            e.getAnnotation(XmlEnum.class);
                        if (xmlEnum != null) {
                            Class argClass = xmlEnum.value();
                            m = fromValueMethod(e, argClass);
                            if (m !=null) {
                                return argClass;
                            }
                            Class primitiveClass = getPrimitiveClass(argClass);
                            if (primitiveClass != null) {
                                m = fromValueMethod(e, primitiveClass);
                                if (m != null) {
                                    return argClass;
                                }
                            }
                        }
                        
                        // If still not found look for valueOf(String) method
                        if (log.isDebugEnabled()) {
                            log.debug("try looking for valueOf method ");
                        }
                        m = valueOfMethod(e);
                        if (m != null) {
                            return String.class;
                        }
                       
                        throw ExceptionFactory.makeWebServiceException(new IllegalArgumentException());
                    }});
        } finally {
            if (log.isDebugEnabled()) {
                log.debug("getConversionType is" + cls);
            }
        }    
        return cls;
    }
    
    /**
     * @param e enumeration class
     * @param convObject Object of conversion type
     * @return Object of enum
     */
    public static Object fromValue(final Class e, final Object convObject) {
        Object enumValue = null;
        if (log.isDebugEnabled()) {
            log.debug("fromValue for " + JavaUtils.getObjectIdentity(convObject));
        }
        try {
            enumValue =      
                AccessController.doPrivileged(new PrivilegedExceptionAction() {
                    public Object run() throws InvocationTargetException, IllegalAccessException {
                        Method m = getConversionMethod(e);
                        return m.invoke(null, new Object[] { convObject });
                    }});
        } catch (PrivilegedActionException pae) {
            throw ExceptionFactory.makeWebServiceException(pae.getException());
        } finally {
            if (log.isDebugEnabled()) {
                log.debug("getEnumValue is" + JavaUtils.getObjectIdentity(enumValue));
            }
        }
        return enumValue;
    }
    
    private static Method getConversionMethod(Class cls) {
        // Look for forName method that is generated by JAXB.
        Method m = fromValueMethod(cls, String.class);
        if (m != null) {
            return m;
        }
        
        // If cannot find forName(String) then look for @XmlEnum value
        if (log.isDebugEnabled()) {
            log.debug("try looking for @XmlEnum ");
        }
        XmlEnum xmlEnum = (XmlEnum)
            cls.getAnnotation(XmlEnum.class);
        if (xmlEnum != null) {
            Class argClass = xmlEnum.value();
            m = fromValueMethod(cls, argClass);
            if (m !=null) {
                return m;
            }
            Class primitiveClass = getPrimitiveClass(argClass);
            if (primitiveClass != null) {
                m = fromValueMethod(cls, primitiveClass);
                if (m != null) {
                    return m;
                }
            }
        }
        
        // Look for valueOf(String) method
        if (log.isDebugEnabled()) {
            log.debug("try looking for valueOf method ");
        }
        m = valueOfMethod(cls);
        if (m != null) {
            return m;
        }
        
        throw new IllegalArgumentException();
    }
    /**
     * @param cls
     * @param argClass
     * @return Method of fromValue with argClass
     */
    private static Method fromValueMethod(Class cls, Class argClass) {
        try {
            return cls.getMethod("fromValue", new Class[] { argClass });
        } catch (Throwable t) {
            return null;
        }
    }
    
    /**
     * @param cls
     * @param argClass
     * @return Method of valueOf with argClass
     */
    private static Method valueOfMethod(Class cls) {
        try {
            return cls.getMethod("valueOf", new Class[] { String.class });
        } catch (Throwable t) {
            return null;
        }
    }
    
    /*
     * @param cls possible wrapper class
     * @return primitive class if this is a wrapper class
     */
    private static Class getPrimitiveClass(Class cls) {
        if (Integer.class.equals(cls)) {
            return int.class;
        } else if (Short.class.equals(cls)) {
            return short.class;
        } else if (Boolean.class.equals(cls)) {
            return boolean.class;
        } else if (Byte.class.equals(cls)) {
            return byte.class;
        } else if (Long.class.equals(cls)) {
            return long.class;
        } else if (Double.class.equals(cls)) {
            return double.class;
        } else if (Float.class.equals(cls)) {
            return float.class;
        } else if (Character.class.equals(cls)) {
            return char.class;
        }

        return null;
    }
    
}
