//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.start;

/**
 * Utility class for parsing and comparing version strings.
 * <p>
 * http://www.oracle.com/technetwork/java/javase/namechange-140185.html
 */
public class Version implements Comparable<Version>
{
    
    /**
     * Original String version
     */
    private String string = null;
    
    /**
     * Short String version
     */
    private String shortString = null;
    
    /**
     * The major version for java is always "1" (per
     * <a href="http://www.oracle.com/technetwork/java/javase/namechange-140185.html">legacy versioning history</a>)
     */
    private int legacyMajor = 0;
    /**
     * The true major version is the second value ("1.5" == "Java 5", "1.8" = "Java 8", etc..)
     */
    private int major = -1;
    /**
     * The revision of the version.
     * <p>
     * This value is always "0" (also per <a
     * href="http://www.oracle.com/technetwork/java/javase/namechange-140185.html">legacy versioning history</a>)
     */
    private int revision = -1;
    /**
     * The update (where bug fixes are placed)
     */
    private int update = -1;
    
    /**
     * Update strings may be zero padded!
     */
    private String updateString = null;
    
    /**
     * Extra versioning information present on the version string, but not relevant for version comparison reason.
     * (eg: with "1.8.0_45-internal", the suffix would be "-internal")
     */
    private String suffix = "";

    private static enum ParseState
    {
        LEGACY,
        MAJOR,
        REVISION,
        UPDATE;
    }

    public Version(String versionString)
    {
        parse(versionString);
    }

    @Override
    /**
     * Compares with other version. Does not take extension into account, as there is no reliable way to order them.
     * 
     * @param other the other version to compare this to 
     * @return -1 if this is older version that other, 0 if its same version, 1 if it's newer version than other
     */
    public int compareTo(Version other)
    {
        if (other == null)
        {
            throw new NullPointerException("other version is null");
        }
        if (this.legacyMajor < other.legacyMajor)
        {
            return -1;
        }
        if (this.legacyMajor > other.legacyMajor)
        {
            return 1;
        }
        if (this.major < other.major)
        {
            return -1;
        }
        if (this.major > other.major)
        {
            return 1;
        }
        if (this.revision < other.revision)
        {
            return -1;
        }
        if (this.revision > other.revision)
        {
            return 1;
        }
        if (this.update < other.update)
        {
            return -1;
        }
        if (this.update > other.update)
        {
            return 1;
        }
        return 0;
    }

    public int getLegacyMajor()
    {
        return legacyMajor;
    }

    public int getMajor()
    {
        return major;
    }

    public int getRevision()
    {
        return revision;
    }

    public int getUpdate()
    {
        return update;
    }

    public String getSuffix()
    {
        return suffix;
    }

    public boolean isNewerThan(Version other)
    {
        return compareTo(other) == 1;
    }

    public boolean isNewerThanOrEqualTo(Version other)
    {
        int comp = compareTo(other);
        return (comp == 0) || (comp == 1);
    }

    public boolean isOlderThan(Version other)
    {
        return compareTo(other) == -1;
    }

    public boolean isOlderThanOrEqualTo(Version other)
    {
        int comp = compareTo(other);
        return (comp == 0) || (comp == -1);
    }

    /**
     * Check whether this version is in range of versions specified
     * 
     * @param low
     *            the low part of the range
     * @param high
     *            the high part of the range
     * @return true if this version is within the provided range
     */
    public boolean isInRange(Version low, Version high)
    {
        return ((compareTo(low) >= 0) && (compareTo(high) <= 0));
    }

    /**
     * parses version string in the form legacy[.major[.revision[_update[-suffix]]]] into this instance.
     * 
     * @param versionStr
     *            the version string
     */
    private void parse(String versionStr)
    {
        string = versionStr;
        legacyMajor = 0;
        major = -1;
        revision = -1;
        update = -1;
        suffix = "";

        ParseState state = ParseState.LEGACY;
        int offset = 0;
        int len = versionStr.length();
        int val = 0;
        while (offset < len)
        {
            char c = versionStr.charAt(offset);
            if (c=='-')
                shortString=versionStr.substring(0,offset);
            boolean isSeparator = !Character.isLetterOrDigit(c);
            if (isSeparator)
            {
                val = 0;
            }
            else if (Character.isDigit(c))
            {
                val = (val * 10) + (c - '0');
            }
            else if (Character.isLetter(c))
            {
                suffix = versionStr.substring(offset);
                break;
            }

            switch (state)
            {
                case LEGACY:
                    if (isSeparator)
                        state = ParseState.MAJOR;
                    else
                        legacyMajor = val;
                    break;
                case MAJOR:
                    if (isSeparator)
                        state = ParseState.REVISION;
                    else
                        major = val;
                    break;
                case REVISION:
                    if (isSeparator)
                        state = ParseState.UPDATE;
                    else
                        revision = val;
                    break;
                case UPDATE:
                    if (!isSeparator)
                    {
                        update = val;
                    }
                    break;
            }

            offset++;
        }
        if (shortString==null)
            shortString=versionStr;
    }

    /**
     * @return string representation of this version
     */
    @Override
    public String toString()
    {
        return string;
    }
    
    /**
     * Return short string form (without suffix)
     * @return string the short version string form
     */
    public String toShortString()
    {
        return shortString;
    }
}
