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

import org.hamcrest.Description;
import org.hamcrest.StringDescription;
import org.onlab.junit.TestUtils.TestUtilsException;

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


/**
 * Hamcrest style class for verifying that a class follows the
 * accepted rules for utility classes.
 *
 * The rules that are enforced for utility classes:
 *    - the class must be declared final
 *    - the class must have only one constructor
 *    - the constructor must be private and inaccessible to callers
 *    - the class must have only static methods
 */

public class UtilityClassChecker {

    private String failureReason = "";

    /**
     * Method to determine if a given class is a properly specified
     * utility class.  In addition to checking that the class meets the criteria
     * for utility classes, an object of the class type is allocated to force
     * test code coverage onto the class constructor.
     *
     * @param clazz the class to check
     * @return true if the given class is a properly specified utility class.
     */
    private boolean isProperlyDefinedUtilityClass(Class<?> clazz) {
        // class must be declared final
        if (!Modifier.isFinal(clazz.getModifiers())) {
            failureReason = "a class that is not final";
            return false;
        }

        // class must have only one constructor
        final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
        if (constructors.length != 1) {
            failureReason = "a class with more than one constructor";
            return false;
        }

        //  constructor must not be accessible outside of the class
        final Constructor<?> constructor = constructors[0];
        if (constructor.isAccessible()) {
            failureReason = "a class with an accessible default constructor";
            return false;
        }

        // constructor must be private
        if (!Modifier.isPrivate(constructor.getModifiers())) {
            failureReason = "a class with a default constructor that is not private";
            return false;
        }

        // class must have only static methods
        for (final Method method : clazz.getMethods()) {
            if (method.getDeclaringClass().equals(clazz)) {
                if (!Modifier.isStatic(method.getModifiers())) {
                    failureReason = "a class with one or more non-static methods";
                    return false;
                }
            }

        }

        try {
            final Object newObject = TestUtils.callConstructor(constructor);
            if (newObject == null) {
                failureReason = "could not instantiate a new object";
                return false;
            }
        } catch (TestUtilsException e) {
            failureReason = "could not instantiate a new object";
            return false;
        }
        return true;
    }

    /**
     * Describe why an error was reported.  Uses Hamcrest style Description
     * interfaces.
     *
     * @param description the Description object to use for reporting the
     *                    mismatch
     */
    public void describeMismatch(Description description) {
        description.appendText(failureReason);
    }

    /**
     * Describe the source object that caused an error, using a Hamcrest
     * Matcher style interface.  In this case, it always returns
     * that we are looking for a properly defined utility class.
     *
     * @param description the Description object to use to report the "to"
     *                    object
     */
    public void describeTo(Description description) {
        description.appendText("a properly defined utility class");
    }

    /**
     * Assert that the given class adheres to the utility class rules.
     *
     * @param clazz the class to check
     *
     * @throws java.lang.AssertionError if the class is not a valid
     *         utility class
     */
    public static void assertThatClassIsUtility(Class<?> clazz) {
        final UtilityClassChecker checker = new UtilityClassChecker();
        if (!checker.isProperlyDefinedUtilityClass(clazz)) {
            final Description toDescription = new StringDescription();
            final Description mismatchDescription = new StringDescription();

            checker.describeTo(toDescription);
            checker.describeMismatch(mismatchDescription);
            final String reason =
                "\n" +
                "Expected: is \"" + toDescription.toString() + "\"\n" +
                "    but : was \"" + mismatchDescription.toString() + "\"";

            throw new AssertionError(reason);
        }
    }
}
