/*
 * 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.commons.proxy2;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Provides some helpful proxy utility methods.
 * 
 * @author James Carman
 * @since 1.0
 */
public final class ProxyUtils
{
    //******************************************************************************************************************
    // Fields
    //******************************************************************************************************************

    public static final Object[] EMPTY_ARGUMENTS = new Object[0];
    public static final Class<?>[] EMPTY_ARGUMENT_TYPES = new Class[0];
    private static final Map<Class<?>, Class<?>> WRAPPER_CLASS_MAP = new HashMap<Class<?>, Class<?>>();
    private static final Map<Class<?>, Object> NULL_VALUE_MAP = new HashMap<Class<?>, Object>();

    //******************************************************************************************************************
    // Static Methods
    //******************************************************************************************************************

    static
    {
        WRAPPER_CLASS_MAP.put(Integer.TYPE, Integer.class);
        WRAPPER_CLASS_MAP.put(Character.TYPE, Character.class);
        WRAPPER_CLASS_MAP.put(Boolean.TYPE, Boolean.class);
        WRAPPER_CLASS_MAP.put(Short.TYPE, Short.class);
        WRAPPER_CLASS_MAP.put(Long.TYPE, Long.class);
        WRAPPER_CLASS_MAP.put(Float.TYPE, Float.class);
        WRAPPER_CLASS_MAP.put(Double.TYPE, Double.class);
        WRAPPER_CLASS_MAP.put(Byte.TYPE, Byte.class);
    }

    static
    {
        NULL_VALUE_MAP.put(Integer.TYPE, 0);
        NULL_VALUE_MAP.put(Long.TYPE, (long) 0);
        NULL_VALUE_MAP.put(Short.TYPE, (short) 0);
        NULL_VALUE_MAP.put(Byte.TYPE, (byte) 0);
        NULL_VALUE_MAP.put(Float.TYPE, 0.0f);
        NULL_VALUE_MAP.put(Double.TYPE, 0.0);
        NULL_VALUE_MAP.put(Character.TYPE, (char) 0);
        NULL_VALUE_MAP.put(Boolean.TYPE, Boolean.FALSE);
    }

    /**
     * <p>
     * Gets an array of {@link Class} objects representing all interfaces implemented by the given class and its
     * superclasses.
     * </p>
     * <p/>
     * <p>
     * The order is determined by looking through each interface in turn as declared in the source file and following
     * its hierarchy up. Then each superclass is considered in the same way. Later duplicates are ignored, so the order
     * is maintained.
     * </p>
     * <p/>
     * <b>Note</b>: Implementation of this method was "borrowed" from <a href="http://commons.apache.org/lang/">Apache
     * Commons Lang</a> to avoid a dependency.
     * </p>
     * 
     * @param cls
     *            the class to look up, may be <code>null</code>
     * @return an array of {@link Class} objects representing all interfaces implemented by the given class and its
     *         superclasses or <code>null</code> if input class is null.
     */
    public static Class<?>[] getAllInterfaces(Class<?> cls)
    {
        final List<Class<?>> interfaces = getAllInterfacesImpl(cls, new LinkedList<Class<?>>());
        return interfaces == null ? null : (Class[]) interfaces.toArray(new Class[interfaces.size()]);
    }

    private static List<Class<?>> getAllInterfacesImpl(final Class<?> cls, List<Class<?>> list)
    {
        if (cls == null)
        {
            return null;
        }
        Class<?> currentClass = cls;
        while (currentClass != null)
        {
            Class<?>[] interfaces = currentClass.getInterfaces();
            for (int i = 0; i < interfaces.length; i++)
            {
                if (!list.contains(interfaces[i]))
                {
                    list.add(interfaces[i]);
                }
                getAllInterfacesImpl(interfaces[i], list);
            }
            currentClass = currentClass.getSuperclass();
        }
        return list;
    }

    /**
     * Returns the class name as you would expect to see it in Java code.
     * <p/>
     * <b>Examples:</b>
     * <ul>
     * <li>getJavaClassName( Object[].class ) == "Object[]"</li>
     * <li>getJavaClassName( Object[][].class ) == "Object[][]"</li>
     * <li>getJavaClassName( Integer.TYPE ) == "int"</li>
     * </p>
     * 
     * @param clazz
     *            the class
     * @return the class' name as you would expect to see it in Java code
     */
    public static String getJavaClassName(Class<?> clazz)
    {
        if (clazz.isArray())
        {
            return getJavaClassName(clazz.getComponentType()) + "[]";
        }
        return clazz.getName();
    }

    /**
     * Returns the wrapper class for the given primitive type.
     * 
     * @param primitiveType
     *            the primitive type
     * @return the wrapper class
     */
    public static Class<?> getWrapperClass(Class<?> primitiveType)
    {
        return WRAPPER_CLASS_MAP.get(primitiveType);
    }

    /**
     * Returns the proper "null value" as specified by the Java language.
     * 
     * @param type
     *            the type
     * @return the null value
     */
    @SuppressWarnings("unchecked")
    public static <T> T nullValue(Class<T> type)
    {
        return (T) NULL_VALUE_MAP.get(type);
    }

    /**
     * Learn whether the specified method is/overrides {@link Object#equals(Object)}.
     * 
     * @param method
     *            to compare
     * @return <code>true</code> for a method with signature <code>boolean equals(Object)</code>
     */
    public static boolean isEqualsMethod(Method method)
    {
        return "equals".equals(method.getName()) && Boolean.TYPE.equals(method.getReturnType())
                && method.getParameterTypes().length == 1 && Object.class.equals(method.getParameterTypes()[0]);
    }

    /**
     * Learn whether the specified method is/overrides {@link Object#hashCode()}.
     * 
     * @param method
     *            to compare
     * @return true for a method with signature <code>int hashCode()</code>
     */
    public static boolean isHashCode(Method method)
    {
        return "hashCode".equals(method.getName()) && Integer.TYPE.equals(method.getReturnType())
                && method.getParameterTypes().length == 0;
    }

    /**
     * Get a {@link ProxyFactory} that delegates to discoverable {@link ProxyFactory} service providers.
     * 
     * @return {@link ProxyFactory}
     */
    public static ProxyFactory proxyFactory()
    {
        return DefaultProxyFactory.INSTANCE;
    }

    private ProxyUtils()
    {
        // Hiding constructor in utility class!
    }
}
