/*
 * 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.impl;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.LinkedHashSet;
import java.util.Set;

import org.apache.commons.proxy2.exception.ProxyFactoryException;

/**
 * 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<?>>();
        for (Class<?> proxyClass : proxyClasses)
        {
            if (proxyClass.isInterface())
            {
                interfaces.add(proxyClass);
            }
        }
        interfaces.add(Serializable.class);
        return 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());
        }
    }
}
