//
//  ========================================================================
//  Copyright (c) 1995-2016 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>
{
    /**
     * 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;
    /**
     * 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)
    {
        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);
            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);
                return;
            }

            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++;
        }
    }

    /**
     * @return string representation of this version
     */
    @Override
    public String toString()
    {
        StringBuffer sb = new StringBuffer(10);
        sb.append(legacyMajor);
        if (major >= 0)
        {
            sb.append('.').append(major);
            if (revision >= 0)
            {
                sb.append('.').append(revision);
                if (update >= 0)
                {
                    sb.append('_').append(update);
                }
            }
        }
        if (Utils.isNotBlank(suffix))
        {
            sb.append('-').append(suffix);
        }
        return sb.toString();
    }
    
    /**
     * Return short string form (without suffix)
     * @return string the short version string form
     */
    public String toShortString()
    {
        StringBuffer sb = new StringBuffer(10);
        sb.append(legacyMajor);
        if (major >= 0)
        {
            sb.append('.').append(major);
            if (revision >= 0)
            {
                sb.append('.').append(revision);
                if (update >= 0)
                {
                    sb.append('_').append(update);
                }
            }
        }
        return sb.toString();
    }
}
