# Copyright (C) 2007, 2009, 2010, 2011 Aaron Bentley.
# Copyright (C) 2009 Max Bowsher.
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


import bzrlib
from bzrlib import commands

from version import version_info, __version__


_testing = False
# True if we are currently testing commands via the test suite.

def _stop_testing():
    """Set the _testing flag to indicate we are no longer testing."""
    global _testing
    _testing = False


class BzrToolsCommand(commands.Command):

    def run_argv_aliases(self, argv, alias_argv=None):
        result = check_bzrlib_version(version_info[:2])
        if result is not None:
            return result
        commands.Command.run_argv_aliases(self, argv, alias_argv)


TOO_OLD = 'too_old'
COMPATIBLE = 'compatible'
MAYBE_TOO_NEW = 'maybe_too_new'
TOO_NEW = 'too_new'


def check_version_compatibility(bzrlib_version, min_version, max_version):
    """Check whether a bzrlib version is compatible with desired version.

    If the bzrlib_version is not less than min_version and not greater than
    max_version, it is considered COMPATIBLE.  If the version exceeds
    max_version by 1 and is not a 'candidate' or 'final' version, it is
    considered MAYBE_TOO_NEW.  Other values greater than max_version are
    considered TOO_NEW, and values lower than min_version are considered
    TOO_OLD.
    """
    bzrlib_version = bzrlib.version_info[:2]
    if bzrlib_version < min_version:
        return TOO_OLD
    if bzrlib_version <= max_version:
        return COMPATIBLE
    max_plus = (max_version[0], max_version[1] + 1)
    if bzrlib_version == max_plus:
        if bzrlib.version_info[3] not in ('final', 'candidate'):
            return COMPATIBLE
        return MAYBE_TOO_NEW
    return TOO_NEW


def check_bzrlib_version(desired):
    """Check that bzrlib is compatible.

    If version is < bzrtools version, assume incompatible.
    If version == bzrtools version, assume completely compatible
    If version == bzrtools version + 1, assume compatible, with deprecations
    Otherwise, assume incompatible.
    """
    global _testing
    if _testing:
        return
    compatibility = check_version_compatibility(bzrlib.version_info, desired,
                                                desired)
    if compatibility == COMPATIBLE:
        return
    try:
        from bzrlib.trace import warning
    except ImportError:
        # get the message out any way we can
        from warnings import warn as warning
    if compatibility == TOO_OLD:
        warning('Bazaar version %s is too old to be used with'
                ' plugin "Bzrtools" %s.' % (
                bzrlib.__version__, __version__))
        # Not using BzrNewError, because it may not exist.
        return 3
    else:
        warning('Plugin "Bzrtools" is not up to date with installed Bazaar'
                ' version %s.\n'
                'There should be a newer version of Bzrtools available, e.g.'
                ' %i.%i.'
                % (bzrlib.__version__, bzrlib.version_info[0],
                   bzrlib.version_info[1]))
        if compatibility == TOO_NEW:
            return 3
