package org.apache.commons.proxy2.impl;

import org.apache.commons.proxy2.exception.ProxyFactoryException;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * Parent {@link AbstractProxyFactory} for implementations that permit the generation of
 * proxies with a specific inheritance hierarchy.
 */
public abstract class AbstractSubclassingProxyFactory extends AbstractProxyFactory
{
//**********************************************************************************************************************
// ProxyFactory Implementation
//**********************************************************************************************************************

    /**
     * Returns true if a suitable superclass can be found, given the desired <code>proxyClasses</code>.
     *
     * @param proxyClasses the proxy classes
     * @return true if a suitable superclass can be found, given the desired <code>proxyClasses</code>
     */
    public boolean canProxy( Class<?>... proxyClasses )
    {
        try
        {
            getSuperclass(proxyClasses);
            return true;
        }
        catch( ProxyFactoryException e )
        {
            return false;
        }
    }

//**********************************************************************************************************************
// Other Methods
//**********************************************************************************************************************

    private static boolean hasSuitableDefaultConstructor( Class<?> superclass )
    {
        final Constructor<?>[] declaredConstructors = superclass.getDeclaredConstructors();
        for( int i = 0; i < declaredConstructors.length; i++ )
        {
            Constructor<?> constructor = declaredConstructors[i];
            if( constructor.getParameterTypes().length == 0 && ( Modifier.isPublic(constructor.getModifiers()) ||
                    Modifier.isProtected(constructor.getModifiers()) ) )
            {
                return true;
            }
        }
        return false;
    }

    private static Class<?>[] toNonInterfaces( Class<?>[] proxyClasses )
    {
        final Set<Class<?>> superclasses = new LinkedHashSet<Class<?>>();
        for (Class<?> proxyClass : proxyClasses)
        {
            if( !proxyClass.isInterface())
            {
                superclasses.add(proxyClass);
            }
        }
        return superclasses.toArray(new Class[superclasses.size()]);
    }

    /**
     * Returns the <code>proxyClasses</code> transformed into an array of only the interface classes.
     * <p/>
     * <b>Note</b>: This class will append {@link Serializable} to the end of the list if it's
     * not found!
     *
     * @param proxyClasses the proxy classes
     * @return the <code>proxyClasses</code> transformed into an array of only the interface classes
     */
    protected static Class<?>[] toInterfaces( Class<?>[] proxyClasses )
    {
        final Set<Class<?>> interfaces = new LinkedHashSet<Class<?>>();
        boolean serializableFound = false;
        for (Class<?> proxyClass : proxyClasses)
        {
            if( proxyClass.isInterface() )
            {
                interfaces.add(proxyClass);
            }
            serializableFound |= ( Serializable.class.equals(proxyClass) );
        }
        if( !serializableFound )
        {
            interfaces.add(Serializable.class);
        }
        return ( Class[] ) interfaces.toArray(new Class[interfaces.size()]);
    }

    /**
     * Returns either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
     * class from <code>proxyClasses</code>.
     *
     * @param proxyClasses the proxy classes
     * @return either {@link Object} if all of the <code>proxyClasses</code> are interfaces or the single non-interface
     *         class from <code>proxyClasses</code>
     * @throws ProxyFactoryException if multiple non-interface classes are contained in <code>proxyClasses</code> or any
     *                               of the non-interface classes are final
     */
    public static Class<?> getSuperclass( Class<?>[] proxyClasses )
    {
        final Class<?>[] superclasses = toNonInterfaces(proxyClasses);
        switch( superclasses.length )
        {
            case 0:
                return Object.class;
            case 1:
                final Class<?> superclass = superclasses[0];
                if( Modifier.isFinal(superclass.getModifiers()) )
                {
                    throw new ProxyFactoryException(
                            "Proxy class cannot extend " + superclass.getName() + " as it is final.");
                }
                if( !hasSuitableDefaultConstructor(superclass) )
                {
                    throw new ProxyFactoryException("Proxy class cannot extend " + superclass.getName() +
                            ", because it has no visible \"default\" constructor.");
                }
                return superclass;
            default:
                final StringBuilder errorMessage = new StringBuilder("Proxy class cannot extend ");
                for( int i = 0; i < superclasses.length; i++ )
                {
                    Class<?> c = superclasses[i];
                    errorMessage.append(c.getName());
                    if( i != superclasses.length - 1 )
                    {
                        errorMessage.append(", ");
                    }
                }
                errorMessage.append("; multiple inheritance not allowed.");
                throw new ProxyFactoryException(errorMessage.toString());
        }
    }
}
