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

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;

/**
 * <p> Utility reflection methods focused on constructors, modeled after {@link MethodUtils}. </p>
 *
 * <h3>Known Limitations</h3>
 * <h4>Accessing Public Constructors In A Default Access Superclass</h4>
 * <p>There is an issue when invoking public constructors contained in a default access superclass.
 * Reflection locates these constructors fine and correctly assigns them as public.
 * However, an {@code IllegalAccessException} is thrown if the constructors is invoked.</p>
 *
 * <p>{@code ConstructorUtils} contains a workaround for this situation.
 * It will attempt to call {@code setAccessible} on this constructor.
 * If this call succeeds, then the method can be invoked as normal.
 * This call will only succeed when the application has sufficient security privileges.
 * If this call fails then a warning will be logged and the method may fail.</p>
 *
 */
public class ConstructorUtils {


    /** An empty class array */
    private static final Class<?>[] EMPTY_CLASS_PARAMETERS = new Class<?>[0];
    /** An empty object array */
    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];



    /**
     * <p>Convenience method returning new instance of {@code klazz} using a single argument constructor.
     * The formal parameter type is inferred from the actual values of {@code arg}.
     * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
     *
     * <p>The signatures should be assignment compatible.</p>
     *
     * @param <T> the type of the object to be constructed
     * @param klass the class to be constructed.
     * @param arg the actual argument. May be null (this will result in calling the default constructor).
     * @return new instance of {@code klazz}
     *
     * @throws NoSuchMethodException If the constructor cannot be found
     * @throws IllegalAccessException If an error occurs accessing the constructor
     * @throws InvocationTargetException If an error occurs invoking the constructor
     * @throws InstantiationException If an error occurs instantiating the class
     *
     * @see #invokeConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
     */
    public static <T> T invokeConstructor(final Class<T> klass, final Object arg)
        throws
            NoSuchMethodException,
            IllegalAccessException,
            InvocationTargetException,
            InstantiationException {

        final Object[] args = toArray(arg);
        return invokeConstructor(klass, args);
    }

    /**
     * <p>Returns new instance of {@code klazz</code> created using the actual arguments <code>args}.
     * The formal parameter types are inferred from the actual values of {@code args}.
     * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
     *
     * <p>The signatures should be assignment compatible.</p>
     *
     * @param <T> the type of the object to be constructed
     * @param klass the class to be constructed.
     * @param args actual argument array. May be null (this will result in calling the default constructor).
     * @return new instance of {@code klazz}
     *
     * @throws NoSuchMethodException If the constructor cannot be found
     * @throws IllegalAccessException If an error occurs accessing the constructor
     * @throws InvocationTargetException If an error occurs invoking the constructor
     * @throws InstantiationException If an error occurs instantiating the class
     *
     * @see #invokeConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
     */
    public static <T> T invokeConstructor(final Class<T> klass, Object[] args)
        throws
            NoSuchMethodException,
            IllegalAccessException,
            InvocationTargetException,
            InstantiationException {

        if (null == args) {
            args = EMPTY_OBJECT_ARRAY;
        }
        final int arguments = args.length;
        final Class<?> parameterTypes[] = new Class<?>[arguments];
        for (int i = 0; i < arguments; i++) {
            parameterTypes[i] = args[i].getClass();
        }
        return invokeConstructor(klass, args, parameterTypes);
    }

    /**
     * <p>Returns new instance of {@code klazz} created using constructor
     * with signature {@code parameterTypes</code> and actual arguments <code>args}.</p>
     *
     * <p>The signatures should be assignment compatible.</p>
     *
     * @param <T> the type of the object to be constructed
     * @param klass the class to be constructed.
     * @param args actual argument array. May be null (this will result in calling the default constructor).
     * @param parameterTypes parameter types array
     * @return new instance of {@code klazz}
     *
     * @throws NoSuchMethodException if matching constructor cannot be found
     * @throws IllegalAccessException thrown on the constructor's invocation
     * @throws InvocationTargetException thrown on the constructor's invocation
     * @throws InstantiationException thrown on the constructor's invocation
     * @see Constructor#newInstance
     */
    public static <T> T invokeConstructor(
        final Class<T> klass,
        Object[] args,
        Class<?>[] parameterTypes)
        throws
            NoSuchMethodException,
            IllegalAccessException,
            InvocationTargetException,
            InstantiationException {

        if (parameterTypes == null) {
            parameterTypes = EMPTY_CLASS_PARAMETERS;
        }
        if (args == null) {
            args = EMPTY_OBJECT_ARRAY;
        }

        final Constructor<T> ctor =
            getMatchingAccessibleConstructor(klass, parameterTypes);
        if (null == ctor) {
            throw new NoSuchMethodException(
                "No such accessible constructor on object: " + klass.getName());
        }
        return ctor.newInstance(args);
    }

    /**
     * <p>Convenience method returning new instance of {@code klazz} using a single argument constructor.
     * The formal parameter type is inferred from the actual values of {@code arg}.
     * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
     *
     * <p>The signatures should match exactly.</p>
     *
     * @param <T> the type of the object to be constructed
     * @param klass the class to be constructed.
     * @param arg the actual argument. May be null (this will result in calling the default constructor).
     * @return new instance of {@code klazz}
     *
     * @throws NoSuchMethodException If the constructor cannot be found
     * @throws IllegalAccessException If an error occurs accessing the constructor
     * @throws InvocationTargetException If an error occurs invoking the constructor
     * @throws InstantiationException If an error occurs instantiating the class
     *
     * @see #invokeExactConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
     */
    public static <T> T invokeExactConstructor(final Class<T> klass, final Object arg)
        throws
            NoSuchMethodException,
            IllegalAccessException,
            InvocationTargetException,
            InstantiationException {

        final Object[] args = toArray(arg);
        return invokeExactConstructor(klass, args);
    }

    /**
     * <p>Returns new instance of {@code klazz</code> created using the actual arguments <code>args}.
     * The formal parameter types are inferred from the actual values of {@code args}.
     * See {@link #invokeExactConstructor(Class, Object[], Class[])} for more details.</p>
     *
     * <p>The signatures should match exactly.</p>
     *
     * @param <T> the type of the object to be constructed
     * @param klass the class to be constructed.
     * @param args actual argument array. May be null (this will result in calling the default constructor).
     * @return new instance of {@code klazz}
     *
     * @throws NoSuchMethodException If the constructor cannot be found
     * @throws IllegalAccessException If an error occurs accessing the constructor
     * @throws InvocationTargetException If an error occurs invoking the constructor
     * @throws InstantiationException If an error occurs instantiating the class
     *
     * @see #invokeExactConstructor(java.lang.Class, java.lang.Object[], java.lang.Class[])
     */
    public static <T> T invokeExactConstructor(final Class<T> klass, Object[] args)
        throws
            NoSuchMethodException,
            IllegalAccessException,
            InvocationTargetException,
            InstantiationException {

        if (null == args) {
            args = EMPTY_OBJECT_ARRAY;
        }
        final int arguments = args.length;
        final Class<?> parameterTypes[] = new Class[arguments];
        for (int i = 0; i < arguments; i++) {
            parameterTypes[i] = args[i].getClass();
        }
        return invokeExactConstructor(klass, args, parameterTypes);
    }

    /**
     * <p>Returns new instance of {@code klazz} created using constructor
     * with signature {@code parameterTypes} and actual arguments
     * {@code args}.</p>
     *
     * <p>The signatures should match exactly.</p>
     *
     * @param <T> the type of the object to be constructed
     * @param klass the class to be constructed.
     * @param args actual argument array. May be null (this will result in calling the default constructor).
     * @param parameterTypes parameter types array
     * @return new instance of {@code klazz}
     *
     * @throws NoSuchMethodException if matching constructor cannot be found
     * @throws IllegalAccessException thrown on the constructor's invocation
     * @throws InvocationTargetException thrown on the constructor's invocation
     * @throws InstantiationException thrown on the constructor's invocation
     * @see Constructor#newInstance
     */
    public static <T> T invokeExactConstructor(
        final Class<T> klass,
        Object[] args,
        Class<?>[] parameterTypes)
        throws
            NoSuchMethodException,
            IllegalAccessException,
            InvocationTargetException,
            InstantiationException {

        if (args == null) {
            args = EMPTY_OBJECT_ARRAY;
        }

        if (parameterTypes == null) {
            parameterTypes = EMPTY_CLASS_PARAMETERS;
        }

        final Constructor<T> ctor = getAccessibleConstructor(klass, parameterTypes);
        if (null == ctor) {
            throw new NoSuchMethodException(
                "No such accessible constructor on object: " + klass.getName());
        }
        return ctor.newInstance(args);
    }

    /**
     * Returns a constructor with single argument.
     * @param <T> the type of the constructor
     * @param klass the class to be constructed
     * @param parameterType The constructor parameter type
     * @return null if matching accessible constructor can not be found.
     * @see Class#getConstructor
     * @see #getAccessibleConstructor(java.lang.reflect.Constructor)
     */
    public static <T> Constructor<T> getAccessibleConstructor(
        final Class<T> klass,
        final Class<?> parameterType) {

        final Class<?>[] parameterTypes = { parameterType };
        return getAccessibleConstructor(klass, parameterTypes);
    }

    /**
     * Returns a constructor given a class and signature.
     * @param <T> the type to be constructed
     * @param klass the class to be constructed
     * @param parameterTypes the parameter array
     * @return null if matching accessible constructor can not be found
     * @see Class#getConstructor
     * @see #getAccessibleConstructor(java.lang.reflect.Constructor)
     */
    public static <T> Constructor<T> getAccessibleConstructor(
        final Class<T> klass,
        final Class<?>[] parameterTypes) {

        try {
            return getAccessibleConstructor(
                klass.getConstructor(parameterTypes));
        } catch (final NoSuchMethodException e) {
            return null;
        }
    }

    /**
     * Returns accessible version of the given constructor.
     * @param <T> the type of the constructor
     * @param ctor prototype constructor object.
     * @return {@code null} if accessible constructor can not be found.
     * @see java.lang.SecurityManager
     */
    public static <T> Constructor<T> getAccessibleConstructor(final Constructor<T> ctor) {

        // Make sure we have a method to check
        if (ctor == null) {
            return null;
        }

        // If the requested method is not public we cannot call it
        if (!Modifier.isPublic(ctor.getModifiers())) {
            return null;
        }

        // If the declaring class is public, we are done
        final Class<T> clazz = ctor.getDeclaringClass();
        if (Modifier.isPublic(clazz.getModifiers())) {
            return ctor;
        }

        // what else can we do?
        return null;
    }

    private static Object[] toArray(final Object arg) {
        Object[] args = null;
        if (arg != null) {
            args = new Object[] { arg };
        }
        return args;
    }


    /**
     * <p>Find an accessible constructor with compatible parameters.
     * Compatible parameters mean that every method parameter is assignable from
     * the given parameters. In other words, it finds constructor that will take
     * the parameters given.</p>
     *
     * <p>First it checks if there is constructor matching the exact signature.
     * If no such, all the constructors of the class are tested if their signatures
     * are assignment compatible with the parameter types.
     * The first matching constructor is returned.</p>
     *
     * @param <T> the type of the class to be inspected
     * @param clazz find constructor for this class
     * @param parameterTypes find method with compatible parameters
     * @return a valid Constructor object. If there's no matching constructor, returns {@code null}.
     */
    private static <T> Constructor<T> getMatchingAccessibleConstructor(
        final Class<T> clazz,
        final Class<?>[] parameterTypes) {
        // see if we can find the method directly
        // most of the time this works and it's much faster
        try {
            final Constructor<T> ctor = clazz.getConstructor(parameterTypes);
            try {
                //
                // XXX Default access superclass workaround
                //
                // When a public class has a default access superclass
                // with public methods, these methods are accessible.
                // Calling them from compiled code works fine.
                //
                // Unfortunately, using reflection to invoke these methods
                // seems to (wrongly) to prevent access even when the method
                // modifier is public.
                //
                // The following workaround solves the problem but will only
                // work from sufficiently privileges code.
                //
                // Better workarounds would be gratefully accepted.
                //
                ctor.setAccessible(true);
            } catch (final SecurityException se) {
                /* SWALLOW, if workaround fails don't fret. */
            }
            return ctor;

        } catch (final NoSuchMethodException e) { /* SWALLOW */
        }

        // search through all methods
        final int paramSize = parameterTypes.length;
        final Constructor<?>[] ctors = clazz.getConstructors();
        for (final Constructor<?> ctor2 : ctors) {
            // compare parameters
            final Class<?>[] ctorParams = ctor2.getParameterTypes();
            final int ctorParamSize = ctorParams.length;
            if (ctorParamSize == paramSize) {
                boolean match = true;
                for (int n = 0; n < ctorParamSize; n++) {
                    if (!MethodUtils
                        .isAssignmentCompatible(
                            ctorParams[n],
                            parameterTypes[n])) {
                        match = false;
                        break;
                    }
                }

                if (match) {
                    // get accessible version of method
                    final Constructor<?> ctor = getAccessibleConstructor(ctor2);
                    if (ctor != null) {
                        try {
                            ctor.setAccessible(true);
                        } catch (final SecurityException se) {
                            /* Swallow SecurityException
                             * TODO: Why?
                             */
                        }
                        @SuppressWarnings("unchecked")
                        final
                        // Class.getConstructors() actually returns constructors
                        // of type T, so it is safe to cast.
                        Constructor<T> typedCtor = (Constructor<T>) ctor;
                        return typedCtor;
                    }
                }
            }
        }

        return null;
    }

}
