/*
 * Copyright 2014-present 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);
        }
    }
}
