package org.onlab.util;

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);
        }
    }
}
