/*
 * 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.apache.sis.util;


/**
 * Specifies the level of strictness when comparing two {@link LenientComparable} objects
 * for equality. This enumeration allows users to specify which kind of differences can be
 * tolerated between two objects: differences in implementation class, differences in
 * some kinds of property, or slight difference in numerical values.
 *
 * <p>This enumeration is <em>ordered</em> from stricter to more lenient levels:</p>
 *
 * <ol>
 *   <li>{@link #STRICT}          – All attributes of the compared objects shall be strictly equal.</li>
 *   <li>{@link #BY_CONTRACT}     – Only the attributes published in the interface contract need to be compared.</li>
 *   <li>{@link #IGNORE_METADATA} – Only the attributes relevant to the object functionality are compared.</li>
 *   <li>{@link #APPROXIMATE}     – Only the attributes relevant to the object functionality are compared,
 *                                  with some tolerance threshold on numerical values.</li>
 *   <li>{@link #ALLOW_VARIANT}   – For objects not really equal but related (e.g. CRS using different axis order).</li>
 *   <li>{@link #DEBUG}           – Special mode for figuring out why two objects expected to be equal are not.</li>
 * </ol>
 *
 * If two objects are equal at some level of strictness <var>E</var>, then they should also
 * be equal at all levels listed below <var>E</var> in the above list. For example if two objects
 * are equal at the {@link #BY_CONTRACT} level, then they should also be equal at the
 * {@link #IGNORE_METADATA} level but not necessarily at the {@link #STRICT} level.
 *
 * @author  Martin Desruisseaux (Geomatys)
 * @version 1.0
 *
 * @see LenientComparable#equals(Object, ComparisonMode)
 * @see Utilities#deepEquals(Object, Object, ComparisonMode)
 *
 * @since 0.3
 * @module
 */
public enum ComparisonMode {
    /**
     * All attributes of the compared objects shall be strictly equal. This comparison mode
     * is equivalent to the {@link Object#equals(Object)} method, and must be compliant with
     * the contract documented in that method. In particular, this comparison mode shall be
     * consistent with {@link Object#hashCode()} and be symmetric ({@code A.equals(B)} implies
     * {@code B.equals(A)}).
     *
     * <div class="section">Implementation note</div>
     * In the SIS implementation, this comparison mode usually have the following
     * characteristics (not always, this is only typical):
     *
     * <ul>
     *   <li>The objects being compared need to be the same implementation class.</li>
     *   <li>Private fields are compared directly instead than invoking public getter methods.</li>
     * </ul>
     *
     * @see Object#equals(Object)
     */
    STRICT,

    /**
     * Only the attributes published in some contract (typically a GeoAPI interface) need to be compared.
     * The implementation classes do not need to be the same and some private attributes may be ignored.
     *
     * <p>Note that this comparison mode does <strong>not</strong> guaranteed {@link Object#hashCode()}
     * consistency, neither comparison symmetry (i.e. {@code A.equals(B)} and {@code B.equals(A)} may
     * return different results if the {@code equals} methods are implemented differently).</p>
     *
     * <div class="section">Implementation note</div>
     * In the SIS implementation, this comparison mode usually have the following
     * characteristics (not always, this is only typical):
     *
     * <ul>
     *   <li>The objects being compared need to implement the same GeoAPI interfaces.</li>
     *   <li>Public getter methods are used (no direct access to private fields).</li>
     * </ul>
     */
    BY_CONTRACT,

    /**
     * Only the attributes relevant to the object functionality are compared. Attributes that
     * are only informative can be ignored. This comparison mode is typically less strict than
     * {@link #BY_CONTRACT}.
     *
     * <div class="section">Application to coordinate reference systems</div>
     * If the objects being compared are {@link org.opengis.referencing.crs.CoordinateReferenceSystem} instances,
     * then only the properties relevant to the coordinate localization shall be compared.
     * Metadata like the {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getIdentifiers() identifiers}
     * or the {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getDomainOfValidity() domain of validity},
     * which have no impact on the coordinates being calculated, shall be ignored.
     *
     * <div class="section">Application to coordinate operations</div>
     * If the objects being compared are {@link org.opengis.referencing.operation.MathTransform} instances,
     * then two transforms defined in a different way may be considered equivalent. For example it is possible
     * to define a {@linkplain org.apache.sis.referencing.operation.projection.Mercator Mercator} projection in
     * two different ways, as a <cite>"Mercator (1SP)"</cite> or as a <cite>"Mercator (2SP)"</cite> projection,
     * each having their own set of parameters.
     * The {@link #STRICT} or {@link #BY_CONTRACT} modes shall consider two projections as equal only if their
     * {@linkplain org.apache.sis.referencing.operation.transform.AbstractMathTransform#getParameterValues()
     * parameter values} are strictly identical, while the {@code IGNORE_METADATA} mode can consider
     * those objects as equivalent despite difference in the set of parameters, as long as coordinate
     * transformations still produce the same results.
     *
     * <div class="note"><b>Example:</b> A <cite>"Mercator (2SP)"</cite> projection with a <cite>standard parallel</cite>
     * value of 60° produces the same results than a <cite>"Mercator (1SP)"</cite> projection with a <cite>scale factor</cite>
     * value of 0.5.</div>
     *
     * @see org.apache.sis.util.Utilities#equalsIgnoreMetadata(Object, Object)
     */
    IGNORE_METADATA,

    /**
     * Only the attributes relevant to the object functionality are compared, with some tolerance
     * threshold on numerical values.
     *
     * <div class="section">Application to coordinate operations</div>
     * If two {@link org.opengis.referencing.operation.MathTransform} objects are considered equal according this mode,
     * then for any given identical source position, the two compared transforms shall compute at least approximately
     * the same target position.
     * A small difference is tolerated between the target coordinates calculated by the two math transforms.
     * How small is “small” is implementation dependent — the threshold can not be specified in the current
     * implementation, because of the non-linear nature of map projections.
     *
     * @since 1.0
     */
    APPROXIMATE,

    /**
     * Most but not all attributes relevant to the object functionality are compared.
     * This comparison mode is equivalent to {@link #APPROXIMATE}, except that it
     * ignores some attributes that may differ between objects not equal but related.
     *
     * <p>The main purpose of this method is to verify if two Coordinate Reference Systems (CRS)
     * are approximately equal ignoring axis order.</p>
     *
     * <div class="note"><b>Example:</b>
     * consider two geographic coordinate reference systems with the same attributes except axis order,
     * where one CRS uses (<var>latitude</var>, <var>longitude</var>) axes
     * and the other CRS uses (<var>longitude</var>, <var>latitude</var>) axes.
     * All comparison modes (even {@code APPROXIMATE}) will consider those two CRS as different,
     * except this {@code ALLOW_VARIANT} mode which will consider one CRS to be a variant of the other.
     * </div>
     *
     * @since 0.7
     */
    ALLOW_VARIANT,

    /**
     * Same as {@link #APPROXIMATE}, except that an {@link AssertionError} is thrown if the two
     * objects are not equal and assertions are enabled. The exception message and stack trace help
     * to locate which attributes are not equal. This mode is typically used in assertions like below:
     *
     * {@preformat java
     *     assert Utilities.deepEquals(object1, object2, ComparisonMode.DEBUG);
     * }
     *
     * Note that a comparison in {@code DEBUG} mode may still return {@code false} without
     * throwing an exception, since not all corner cases are tested. The exception is only
     * intended to provide more details for some common cases.
     */
    @Debug
    DEBUG;

    /**
     * Returns {@code true} if this comparison ignores metadata.
     * This method currently returns {@code true} for {@code IGNORE_METADATA}, {@code APPROXIMATE}
     * or {@code DEBUG} only, but this list may be extended in future SIS versions.
     *
     * @return whether this comparison ignore metadata.
     *
     * @since 0.6
     */
    public boolean isIgnoringMetadata() {
        return ordinal() >= IGNORE_METADATA.ordinal();
    }

    /**
     * Returns {@code true} if this comparison uses a tolerance threshold.
     * This method currently returns {@code true} for {@code APPROXIMATE} or {@code DEBUG} only,
     * but this list may be extended in future SIS versions.
     *
     * @return whether this comparison uses a tolerance threshold.
     *
     * @since 1.0
     */
    public boolean isApproximate() {
        return ordinal() >= APPROXIMATE.ordinal();
    }

    /**
     * If the two given objects are equal according one of the modes enumerated in this class,
     * then returns that mode. Otherwise returns {@code null}.
     *
     * <p><b>Note:</b> this method never return the {@link #DEBUG} mode.</p>
     *
     * @param  o1  the first object to compare, or {@code null}.
     * @param  o2  the second object to compare, or {@code null}.
     * @return the most suitable comparison mode, or {@code null} if the two given objects
     *         are not equal according any mode in this enumeration.
     */
    public static ComparisonMode equalityLevel(final Object o1, Object o2) {
        if (o1 == o2) {
            return STRICT;
        }
        if (o1 != null && o2 != null) {
            if (o1.equals(o2)) {
                return STRICT;
            }
            final LenientComparable cp;
            if (o1 instanceof LenientComparable) {
                cp = (LenientComparable) o1;
            } else if (o2 instanceof LenientComparable) {
                cp = (LenientComparable) o2;
                o2 = o1;
            } else {
                return null;
            }
            if (cp.equals(o2, BY_CONTRACT))     return BY_CONTRACT;
            if (cp.equals(o2, IGNORE_METADATA)) return IGNORE_METADATA;
            if (cp.equals(o2, APPROXIMATE))     return APPROXIMATE;
            if (cp.equals(o2, ALLOW_VARIANT))   return ALLOW_VARIANT;
        }
        return null;
    }
}
