package org.onlab.junit;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


/**
 * Utilities for testing.
 */
public final class TestUtils {

    /**
     * Sets the field, bypassing scope restriction.
     *
     * @param subject Object where the field belongs
     * @param fieldName name of the field to set
     * @param value value to set to the field.
     * @param <T> subject type
     * @param <U> value type
     * @throws TestUtilsException if there are reflection errors while setting
     * the field
     */
    public static <T, U> void setField(T subject, String fieldName, U value)
            throws TestUtilsException {
        @SuppressWarnings("unchecked")
        Class<T> clazz = (Class<T>) subject.getClass();
        try {
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(subject, value);
        } catch (NoSuchFieldException | SecurityException |
                 IllegalArgumentException | IllegalAccessException e) {
            throw new TestUtilsException("setField failed", e);
        }
    }

    /**
     * Gets the field, bypassing scope restriction.
     *
     * @param subject Object where the field belongs
     * @param fieldName name of the field to get
     * @return value of the field.
     * @param <T> subject type
     * @param <U> field value type
     * @throws TestUtilsException if there are reflection errors while getting
     * the field
     */
    public static <T, U> U getField(T subject, String fieldName)
            throws TestUtilsException {
        try {
            @SuppressWarnings("unchecked")
            Class<T> clazz = (Class<T>) subject.getClass();
            Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);

            @SuppressWarnings("unchecked")
            U result = (U) field.get(subject);
            return result;
        } catch (NoSuchFieldException | SecurityException |
                 IllegalArgumentException | IllegalAccessException e) {
            throw new TestUtilsException("getField failed", e);
        }
    }

    /**
     * Calls the method, bypassing scope restriction.
     *
     * @param subject Object where the method belongs
     * @param methodName name of the method to call
     * @param paramTypes formal parameter type array
     * @param args arguments
     * @return return value or null if void
     * @param <T> subject type
     * @param <U> return value type
     * @throws TestUtilsException if there are reflection errors while calling
     * the method
     */
    public static <T, U> U callMethod(T subject, String methodName,
            Class<?>[] paramTypes, Object...args) throws TestUtilsException {

        try {
            @SuppressWarnings("unchecked")
            Class<T> clazz = (Class<T>) subject.getClass();
            final Method method;
            if (paramTypes == null || paramTypes.length == 0) {
                method = clazz.getDeclaredMethod(methodName);
            } else {
                method = clazz.getDeclaredMethod(methodName, paramTypes);
            }
            method.setAccessible(true);

            @SuppressWarnings("unchecked")
            U result = (U) method.invoke(subject, args);
            return result;
        } catch (NoSuchMethodException | SecurityException |
                IllegalAccessException | IllegalArgumentException |
                InvocationTargetException e) {
            throw new TestUtilsException("callMethod failed", e);
        }
    }

    /**
     * Calls the method, bypassing scope restriction.
     *
     * @param subject Object where the method belongs
     * @param methodName name of the method to call
     * @param paramType formal parameter type
     * @param arg argument
     * @return return value or null if void
     * @param <T> subject type
     * @param <U> return value type
     * @throws TestUtilsException if there are reflection errors while calling
     * the method
     */
    public static <T, U> U callMethod(T subject, String methodName,
            Class<?> paramType, Object arg) throws TestUtilsException {
        return callMethod(subject, methodName, new Class<?>[]{paramType}, arg);
    }

    /**
     * Triggers an allocation of an object of type <T> and forces a call to
     * the private constructor.
     *
     * @param constructor Constructor to call
     * @param <T> type of the object to create
     * @return created object of type <T>
     * @throws TestUtilsException if there are reflection errors while calling
     * the constructor
     */
    public static <T> T callConstructor(Constructor<T> constructor)
            throws TestUtilsException {
        try {
            constructor.setAccessible(true);
            return constructor.newInstance();
        } catch (InstantiationException | IllegalAccessException |
                InvocationTargetException error) {
            throw new TestUtilsException("callConstructor failed", error);
        }
    }

    /**
     * Avoid instantiation.
     */
    private TestUtils() {}

    /**
     * Exception that can be thrown if problems are encountered while executing
     * the utility method. These are usually problems accessing fields/methods
     * through reflection. The original exception can be found by examining the
     * cause.
     */
    public static class TestUtilsException extends Exception {

        private static final long serialVersionUID = 1L;

        /**
         * Constructs a new exception with the specified detail message and
         * cause.
         *
         * @param message the detail message
         * @param cause the original cause of this exception
         */
        public TestUtilsException(String message, Throwable cause) {
            super(message, cause);
        }
    }
}
