/*
 * 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;

import java.io.Serializable;
import java.util.StringTokenizer;

import static org.apache.sis.internal.system.Modules.MAJOR_VERSION;
import static org.apache.sis.internal.system.Modules.MINOR_VERSION;


/**
 * Holds a version number as a sequence of strings separated by either a dot or a dash.
 * The first three strings, usually numbers, are called respectively {@linkplain #getMajor() major},
 * {@linkplain #getMinor() minor} and {@linkplain #getRevision() revision}.
 * For example a version code such as {@code "6.11.2"} will have major number 6, minor
 * number 11 and revision number 2. Alternatively a version code such as {@code "3.18-SNAPSHOT"}
 * will have major version number 3, minor version number 18 and revision string "SNAPSHOT".
 *
 * <p>This class provides methods for performing comparisons of {@code Version} objects where major,
 * minor and revision parts are compared as numbers when possible, or as strings otherwise.</p>
 *
 * <h2>Immutability and thread safety</h2>
 * This class is immutable and thus inherently thread-safe.
 * Subclasses may or may not be immutable, at implementation choice. But implementers are
 * encouraged to make sure that subclasses remain immutable for more predictable behavior.
 *
 * @author  Martin Desruisseaux (IRD, Geomatys)
 * @version 0.4
 * @since   0.3
 * @module
 */
public class Version implements CharSequence, Comparable<Version>, Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = 8402041502662929792L;

    /**
     * The separator characters between {@linkplain #getMajor() major}, {@linkplain #getMinor() minor}
     * and {@linkplain #getRevision() revision} components. Any character in this string fits.
     */
    private static final String SEPARATORS = ".-";

    /**
     * The version of this Apache SIS distribution.
     */
    public static final Version SIS = new Version(MAJOR_VERSION + "." + MINOR_VERSION + "-SNAPSHOT");

    /**
     * A few commonly used version numbers. This list is based on SIS needs, e.g. in {@code DataStore} implementations.
     * New constants are likely to be added in any future SIS versions.
     *
     * @see #valueOf(int[])
     */
    private static final Version[] CONSTANTS = {
        new Version("1"),
        new Version("2"),
        new Version("1.0"),
        new Version("1.1")
    };

    /**
     * The version in string form, with leading and trailing spaces removed.
     */
    private final String version;

    /**
     * The components of the version string. Will be created when first needed.
     */
    private transient String[] components;

    /**
     * The parsed components of the version string. Will be created when first needed.
     */
    private transient Comparable<?>[] parsed;

    /**
     * The hash code value. Will be computed when first needed.
     */
    private transient int hashCode;

    /**
     * Creates a new version object from the supplied string.
     *
     * @param version  the version as a string.
     */
    public Version(final String version) {
        ArgumentChecks.ensureNonNull("version", version);
        this.version = version;
    }

    /**
     * Returns an instance for the given integer values.
     * The {@code components} array must contain at least 1 element, where:
     *
     * <ul>
     *   <li>The first element is the {@linkplain #getMajor() major} number.</li>
     *   <li>The second element (if any) is the {@linkplain #getMinor() minor} number.</li>
     *   <li>The third element (if any) is the {@linkplain #getRevision() revision} number.</li>
     *   <li>Other elements (if any) will be appended to the {@link #toString() string value}.</li>
     * </ul>
     *
     * @param  components  the major number, optionally followed by minor, revision or other numbers.
     * @return a new or existing instance of {@code Version} for the given numbers.
     *
     * @since 0.4
     */
    public static Version valueOf(final int... components) {
        ArgumentChecks.ensureNonEmpty("components", components, Integer.MIN_VALUE, Integer.MAX_VALUE, false);
        final Version version;
        final int major = components[0];
        if (components.length == 1) {
            if (major >= 1 && major <= CONSTANTS.length) {
                return CONSTANTS[major - 1];
            } else {
                version = new Version(Integer.toString(major));
            }
        } else {
            final StringBuilder buffer = new StringBuilder().append(major);
            for (int i=1; i<components.length; i++) {
                buffer.append('.').append(components[i]);
            }
            version = new Version(buffer.toString());
        }
        /*
         * Pre-compute the 'parsed' array since we already have the integer values. It will avoid the need to
         * create the 'this.components' array and to parse the String values if a 'getFoo()' method is invoked.
         * Note that the cost is typically only the 'parsed' array creation, not Integer objects creation, since
         * version numbers are usually small enough for allowing 'Integer.valueOf(int)' to cache them.
         */
        final Integer[] parsed = new Integer[components.length];
        for (int i=0; i<components.length; i++) {
            parsed[i] = components[i];
        }
        version.parsed = parsed;
        return version;
    }

    /**
     * Returns the major version number. This method returns an {@link Integer} if possible,
     * or a {@link String} otherwise.
     *
     * @return the major version number.
     */
    public Comparable<?> getMajor() {
        return getComponent(0);
    }

    /**
     * Returns the minor version number. This method returns an {@link Integer} if possible,
     * or a {@link String} otherwise. If there is no minor version number, then this method
     * returns {@code null}.
     *
     * @return the minor version number, or {@code null} if none.
     */
    public Comparable<?> getMinor() {
        return getComponent(1);
    }

    /**
     * Returns the revision number. This method returns an {@link Integer} if possible,
     * or a {@link String} otherwise. If there is no revision number, then this method
     * returns {@code null}.
     *
     * @return the revision number, or {@code null} if none.
     */
    public Comparable<?> getRevision() {
        return getComponent(2);
    }

    /**
     * Returns the specified components of this version string. For a version of the
     * {@code major.minor.revision} form, index 0 stands for the major version number,
     * 1 stands for the minor version number and 2 stands for the revision number.
     *
     * <p>The return value is an {@link Integer} if the component is parsable as an integer,
     * or a {@link String} otherwise. If there is no component at the specified index,
     * then this method returns {@code null}.</p>
     *
     * @param  index  the index of the component to fetch.
     * @return the value at the specified index, or {@code null} if none.
     * @throws IndexOutOfBoundsException if {@code index} is negative.
     */
    final synchronized Comparable<?> getComponent(final int index) {
        if (parsed == null) {
            if (components == null) {
                final StringTokenizer tokens = new StringTokenizer(version, SEPARATORS);
                components = new String[tokens.countTokens()];
                for (int i=0; tokens.hasMoreTokens(); i++) {
                    components[i] = tokens.nextToken();
                }
            }
            parsed = new Comparable<?>[components.length];
        }
        if (index >= parsed.length) {
            return null;
        }
        Comparable<?> candidate = parsed[index];
        if (candidate == null) {
            final String value = CharSequences.trimWhitespaces(components[index]);
            try {
                candidate = Integer.valueOf(value);
            } catch (NumberFormatException e) {
                candidate = value;
            }
            parsed[index] = candidate;
        }
        return candidate;
    }

    /**
     * Get the rank of the specified object according this type.
     * This is for {@link #compareTo(Version, int)} internal only.
     */
    private static int getTypeRank(final Object value) {
        if (value instanceof CharSequence) {
            return 0;
        }
        if (value instanceof Number) {
            return 1;
        }
        throw new IllegalArgumentException(String.valueOf(value));
    }

    /**
     * Compares this version with an other version object, up to the specified limit. A limit
     * of 1 compares only the {@linkplain #getMajor() major} version number. A limit of 2 compares
     * the major and {@linkplain #getMinor() minor} version numbers, <i>etc</i>.
     * The comparisons are performed as {@link Integer} object if possible, or as {@link String}
     * otherwise.
     *
     * @param  other  the other version object to compare with.
     * @param  limit  the maximum number of components to compare.
     * @return a negative value if this version is lower than the supplied version,
     *         a positive value if it is higher, or 0 if they are equal.
     */
    public int compareTo(final Version other, final int limit) {
        ArgumentChecks.ensureNonNull ("other", other);
        ArgumentChecks.ensurePositive("limit", limit);
        for (int i=0; i<limit; i++) {
            final Comparable<?> v1 =  this.getComponent(i);
            final Comparable<?> v2 = other.getComponent(i);
            if (v1 == null) {
                return (v2 == null) ? 0 : -1;
            } else if (v2 == null) {
                return +1;
            }
            final int dr = getTypeRank(v1) - getTypeRank(v2);
            if (dr != 0) {
                /*
                 * One value is a text while the other value is a number.  We could be tempted to
                 * force a comparison by converting the number to a String and then invoking the
                 * String.compareTo(String) method, but this strategy would violate the following
                 * contract from Comparable.compareTo(Object):  "The implementer must also ensure
                 * that the relation is transitive". Use case:
                 *
                 *    A is the integer 10
                 *    B is the string "8Z"
                 *    C is the integer 5.
                 *
                 * If mismatched types are converted to String before being compared, then we
                 * would have A < B < C. Transitivity implies that A < C, but if we compare A
                 * and C directly we get A > C because they are compared as numbers.  An easy
                 * way to fix this inconsistency is to define all String as lexicographically
                 * preceding Integer, no matter their content. This is what we do here.
                 */
                return dr;
            }
            @SuppressWarnings({"unchecked","rawtypes"})
            final int c = ((Comparable) v1).compareTo(v2);
            if (c != 0) {
                return c;
            }
        }
        return 0;
    }

    /**
     * Compares this version with an other version object. This method performs the same
     * comparison than {@link #compareTo(Version, int)} with no limit.
     *
     * @param  other  the other version object to compare with.
     * @return a negative value if this version is lower than the supplied version,
     *         a positive value if it is higher, or 0 if they are equal.
     */
    @Override
    public int compareTo(final Version other) {
        return compareTo(other, Integer.MAX_VALUE);
    }

    /**
     * Compare this version string with the specified object for equality. Two version are
     * considered equal if <code>{@linkplain #compareTo(Object) compareTo}(other) == 0</code>.
     *
     * @param other  the object to compare with this version for equality.
     */
    @Override
    public boolean equals(final Object other) {
        if (other != null && getClass() == other.getClass()) {
            return compareTo((Version) other) == 0;
        }
        return false;
    }

    /**
     * Returns the length of the version string.
     */
    @Override
    public int length() {
        return version.length();
    }

    /**
     * Returns the {@code char} value at the specified index.
     */
    @Override
    public char charAt(final int index) {
        return version.charAt(index);
    }

    /**
     * Returns a new version string that is a subsequence of this sequence.
     */
    @Override
    public CharSequence subSequence(final int start, final int end) {
        return version.subSequence(start, end);
    }

    /**
     * Returns the version string. This is the string specified at construction time.
     */
    @Override
    public String toString() {
        return version;
    }

    /**
     * Returns a hash code value for this version.
     */
    @Override
    public int hashCode() {
        if (hashCode == 0) {
            int code = (int) serialVersionUID;
            int index = 0;
            Comparable<?> component;
            while ((component = getComponent(index)) != null) {
                code = code * 31 + component.hashCode();
                index++;
            }
            if (code == 0) {
                code = -1;
            }
            hashCode = code;
        }
        return hashCode;
    }
}
