#!/usr/bin/env python
# -*- coding: utf-8 -*-
# $Id: Util.py 9439 2015-09-25 08:01:30Z Eric $
#
# Copyright (c) 2015 Nuwa Information Co., Ltd, All Rights Reserved.
#
# Licensed under the Proprietary License,
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at our web site.
#
# See the License for the specific language governing permissions and
# limitations under the License.
#
# $Author: Eric $ (last)
# $Date: 2015-09-25 16:01:30 +0800 (Fri, 25 Sep 2015) $
# $Revision: 9439 $
"""
Utilities.
"""

class VersionInfo(object):
    def __init__(self, version='',
                 major=None, minor=None, build=None, revision=None):
        if not version:
            self.major = major
            self.minor = minor
            self.build = build
            self.revision = revision
        else:
            major, minor, build, rev = version.split('.')
            rev = rev.strip()

            wildcard = ('?', '*')
            self.major = int(major) if major not in wildcard else None
            self.minor = int(minor) if minor not in wildcard else None
            self.build = int(build) if build not in wildcard else None
            self.revision = int(rev) if rev not in wildcard else None

    def __key(self):
        return  (self.major, self.minor, self.build, self.revision)

    def __str__(self):
        return '%d.%d.%d.%d' % self.__key()

    def __cmp__(self, other):
        if isinstance(other, basestring):
            return self.__cmp__(VersionInfo(other))

        # Revision is an incremental number, it should compare first.
        if self.revision is not None and other.revision is not None:
            if self.revision > other.revision:
                return 1
            elif self.revision < other.revision:
                return -1

        if self.major is not None and other.major is not None:
            if self.major > other.major:
                return 1
            elif self.major < other.major:
                return -1

        if self.minor is not None and other.minor is not None:
            if self.minor > other.minor:
                return 1
            elif self.minor < other.minor:
                return -1

        if self.build is not None and other.build is not None:
            if self.build > other.build:
                return 1
            elif self.build < other.build:
                return -1

        return 0 # Equal.

    def __eq__(self, other):
        if isinstance(other, basestring):
            return self.__eq__(VersionInfo(other))
        elif not isinstance(other, VersionInfo):
            return False
        else:
            return self.__key() == other.__key()

    def __ne__(self, other):
        if isinstance(other, basestring):
            return self.__ne__(VersionInfo(other))
        else:
            return not self.__eq__(other)

    def __hash__(self):
        return hash(self.__key())
