/*
 * 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 java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * Hamcrest style class for verifying that a class follows the
 * accepted rules for immutable classes.
 *
 * The rules that are enforced for immutable classes:
 *    - the class must be declared final
 *    - all data members of the class must be declared private and final
 *    - the class must not define any setter methods
 */

public class ImmutableClassChecker {

    private String failureReason = "";

    /**
     * Method to determine if a given class is a properly specified
     * immutable class.
     *
     * @param clazz the class to check
     * @return true if the given class is a properly specified immutable class.
     */
    private boolean isImmutableClass(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 final and private data members
        for (final Field field : clazz.getDeclaredFields()) {
            if (field.getName().startsWith("__cobertura")) {
                //  cobertura sticks these fields into classes - ignore them
                continue;
            }
            if (!Modifier.isFinal(field.getModifiers())) {
                failureReason = "a field named '" + field.getName() +
                                "' that is not final";
                return false;
            }
            if (!Modifier.isPrivate(field.getModifiers())) {
                //
                // NOTE: We relax the recommended rules for defining immutable
                // objects and allow "static final" fields that are not
                // private. The "final" check was already done above so we
                // don't repeat it here.
                //
                if (!Modifier.isStatic(field.getModifiers())) {
                    failureReason = "a field named '" + field.getName() +
                                "' that is not private and is not static";
                    return false;
                }
            }
        }

        //  class must not define any setters
        for (final Method method : clazz.getMethods()) {
            if (method.getDeclaringClass().equals(clazz)) {
                if (method.getName().startsWith("set")) {
                    failureReason = "a class with a setter named '" + method.getName() + "'";
                    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 immutable 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 assertThatClassIsImmutable(Class<?> clazz) {
        final ImmutableClassChecker checker = new ImmutableClassChecker();
        if (!checker.isImmutableClass(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);
        }
    }
}
