# 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.

"""
Verion string utilities.
"""

import re


_INF = float('inf')

_NULL = (), _INF

_DIGITS_RE = re.compile(r'^\d+$')

_PREFIXES = {
    'dev':   0.0001,
    'alpha': 0.001,
    'beta':  0.01,
    'rc':    0.1
}


class VersionString(unicode):
    """
    Version string that can be compared, sorted, made unique in a set, and used as a unique dict
    key.

    The primary part of the string is one or more dot-separated natural numbers. Trailing zeroes
    are treated as redundant, e.g. "1.0.0" == "1.0" == "1".

    An optional qualifier can be added after a "-". The qualifier can be a natural number or a
    specially treated prefixed natural number, e.g. "1.1-beta1" > "1.1-alpha2". The case of the
    prefix is ignored.

    Numeric qualifiers will always be greater than prefixed integer qualifiers, e.g. "1.1-1" >
    "1.1-beta1".

    Versions without a qualifier will always be greater than their equivalents with a qualifier,
    e.g. e.g. "1.1" > "1.1-1".

    Any value that does not conform to this format will be treated as a zero version, which would
    be lesser than any non-zero version.

    For efficient list sorts use the ``key`` property, e.g.::

        sorted(versions, key=lambda x: x.key)
    """

    NULL = None # initialized below

    def __init__(self, value=None):
        if value is not None:
            super(VersionString, self).__init__(value)
        self.key = parse_version_string(self)

    def __eq__(self, version):
        if not isinstance(version, VersionString):
            version = VersionString(version)
        return self.key == version.key

    def __lt__(self, version):
        if not isinstance(version, VersionString):
            version = VersionString(version)
        return self.key < version.key

    def __hash__(self):
        return self.key.__hash__()


def parse_version_string(version): # pylint: disable=too-many-branches
    """
    Parses a version string.

    :param version: version string
    :returns: primary tuple and qualifier float
    :rtype: ((:obj:`int`), :obj:`float`)
    """

    if version is None:
        return _NULL
    version = unicode(version)

    # Split to primary and qualifier on '-'
    split = version.split('-', 1)
    if len(split) == 2:
        primary, qualifier = split
    else:
        primary = split[0]
        qualifier = None

    # Parse primary
    split = primary.split('.')
    primary = []
    for element in split:
        if _DIGITS_RE.match(element) is None:
            # Invalid version string
            return _NULL
        try:
            element = int(element)
        except ValueError:
            # Invalid version string
            return _NULL
        primary.append(element)

    # Remove redundant zeros
    for element in reversed(primary):
        if element == 0:
            primary.pop()
        else:
            break
    primary = tuple(primary)

    # Parse qualifier
    if qualifier is not None:
        if _DIGITS_RE.match(qualifier) is not None:
            # Integer qualifier
            try:
                qualifier = float(int(qualifier))
            except ValueError:
                # Invalid version string
                return _NULL
        else:
            # Prefixed integer qualifier
            value = None
            qualifier = qualifier.lower()
            for prefix, factor in _PREFIXES.iteritems():
                if qualifier.startswith(prefix):
                    value = qualifier[len(prefix):]
                    if _DIGITS_RE.match(value) is None:
                        # Invalid version string
                        return _NULL
                    try:
                        value = float(int(value)) * factor
                    except ValueError:
                        # Invalid version string
                        return _NULL
                    break
            if value is None:
                # Invalid version string
                return _NULL
            qualifier = value
    else:
        # Version strings with no qualifiers are higher
        qualifier = _INF

    return primary, qualifier


VersionString.NULL = VersionString()
