/*
 * Copyright 2014 Open Networking Laboratory
 *
 * Licensed 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.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 clazz = subject.getClass();
        try {
            while (clazz != null) {
                try {
                    Field field = clazz.getDeclaredField(fieldName);
                    field.setAccessible(true);
                    field.set(subject, value);
                    break;
                } catch (NoSuchFieldException ex) {
                    if (clazz == clazz.getSuperclass()) {
                        break;
                    }
                    clazz = clazz.getSuperclass();
                }
            }
        } catch (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
     * @param <T>       subject type
     * @param <U>       fieldO value type
     * @return value of the field.
     * @throws TestUtilsException if there are reflection errors while getting
     *                            the field
     */
    public static <T, U> U getField(T subject, String fieldName)
            throws TestUtilsException {
        try {
            NoSuchFieldException exception = null;
            @SuppressWarnings("unchecked")
            Class clazz = subject.getClass();
            while (clazz != null) {
                try {
                    Field field = clazz.getDeclaredField(fieldName);
                    field.setAccessible(true);

                    @SuppressWarnings("unchecked")
                    U result = (U) field.get(subject);
                    return result;
                } catch (NoSuchFieldException e) {
                    exception = e;
                    if (clazz == clazz.getSuperclass()) {
                        break;
                    }
                    clazz = clazz.getSuperclass();
                }
            }
            throw new TestUtilsException("Field not found. " + fieldName, exception);

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