# versions.py -- core Portage functionality
# Copyright 1998-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from __future__ import unicode_literals

__all__ = [
	'best', 'catpkgsplit', 'catsplit',
	'cpv_getkey', 'cpv_getversion', 'cpv_sort_key', 'pkgcmp',  'pkgsplit',
	'ververify', 'vercmp'
]

import re
import sys
import warnings

if sys.hexversion < 0x3000000:
	_unicode = unicode
else:
	_unicode = str

import portage
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.dep:_get_slot_re',
	'portage.repository.config:_gen_valid_repo',
	'portage.util:cmp_sort_key',
)
from portage import _unicode_decode
from portage.eapi import _get_eapi_attrs
from portage.exception import InvalidData
from portage.localization import _

_unknown_repo = "__unknown__"

# \w is [a-zA-Z0-9_]

# 2.1.1 A category name may contain any of the characters [A-Za-z0-9+_.-].
# It must not begin with a hyphen or a dot.
_cat = r'[\w+][\w+.-]*'

# 2.1.2 A package name may contain any of the characters [A-Za-z0-9+_-].
# It must not begin with a hyphen,
# and must not end in a hyphen followed by one or more digits.
_pkg = {
	"dots_disallowed_in_PN": r'[\w+][\w+-]*?',
	"dots_allowed_in_PN":    r'[\w+][\w+.-]*?',
}

_v = r'(cvs\.)?(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)'
_rev = r'\d+'
_vr = _v + '(-r(' + _rev + '))?'

_cp = {
	"dots_disallowed_in_PN": '(' + _cat + '/' + _pkg['dots_disallowed_in_PN'] + '(-' + _vr + ')?)',
	"dots_allowed_in_PN":    '(' + _cat + '/' + _pkg['dots_allowed_in_PN']    + '(-' + _vr + ')?)',
}
_cpv = {
	"dots_disallowed_in_PN": '(' + _cp['dots_disallowed_in_PN'] + '-' + _vr + ')',
	"dots_allowed_in_PN":    '(' + _cp['dots_allowed_in_PN']    + '-' + _vr + ')',
}
_pv = {
	"dots_disallowed_in_PN": '(?P<pn>' + _pkg['dots_disallowed_in_PN'] + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?',
	"dots_allowed_in_PN":    '(?P<pn>' + _pkg['dots_allowed_in_PN']    + '(?P<pn_inval>-' + _vr + ')?)' + '-(?P<ver>' + _v + ')(-r(?P<rev>' + _rev + '))?',
}

ver_regexp = re.compile("^" + _vr + "$")
suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$")
suffix_value = {"pre": -2, "p": 0, "alpha": -4, "beta": -3, "rc": -1}
endversion_keys = ["pre", "p", "alpha", "beta", "rc"]

_pv_re_cache = {}

def _get_pv_re(eapi_attrs):
	cache_key = eapi_attrs.dots_in_PN
	pv_re = _pv_re_cache.get(cache_key)
	if pv_re is not None:
		return pv_re

	if eapi_attrs.dots_in_PN:
		pv_re = _pv['dots_allowed_in_PN']
	else:
		pv_re = _pv['dots_disallowed_in_PN']

	pv_re = re.compile(r'^' + pv_re + r'$', re.VERBOSE | re.UNICODE)

	_pv_re_cache[cache_key] = pv_re
	return pv_re

def ververify(myver, silent=1):
	if ver_regexp.match(myver):
		return 1
	else:
		if not silent:
			print(_("!!! syntax error in version: %s") % myver)
		return 0

def vercmp(ver1, ver2, silent=1):
	"""
	Compare two versions
	Example usage:
		>>> from portage.versions import vercmp
		>>> vercmp('1.0-r1','1.2-r3')
		negative number
		>>> vercmp('1.3','1.2-r3')
		positive number
		>>> vercmp('1.0_p3','1.0_p3')
		0
	
	@param pkg1: version to compare with (see ver_regexp in portage.versions.py)
	@type pkg1: string (example: "2.1.2-r3")
	@param pkg2: version to compare againts (see ver_regexp in portage.versions.py)
	@type pkg2: string (example: "2.1.2_rc5")
	@rtype: None or float
	@return:
	1. positive if ver1 is greater than ver2
	2. negative if ver1 is less than ver2 
	3. 0 if ver1 equals ver2
	4. None if ver1 or ver2 are invalid (see ver_regexp in portage.versions.py)
	"""

	if ver1 == ver2:
		return 0

	match1 = ver_regexp.match(ver1)
	match2 = ver_regexp.match(ver2)
	
	# checking that the versions are valid
	if not match1 or not match1.groups():
		if not silent:
			print(_("!!! syntax error in version: %s") % ver1)
		return None
	if not match2 or not match2.groups():
		if not silent:
			print(_("!!! syntax error in version: %s") % ver2)
		return None

	# shortcut for cvs ebuilds (new style)
	if match1.group(1) and not match2.group(1):
		return 1
	elif match2.group(1) and not match1.group(1):
		return -1
	
	# building lists of the version parts before the suffix
	# first part is simple
	list1 = [int(match1.group(2))]
	list2 = [int(match2.group(2))]

	# this part would greatly benefit from a fixed-length version pattern
	if match1.group(3) or match2.group(3):
		vlist1 = match1.group(3)[1:].split(".")
		vlist2 = match2.group(3)[1:].split(".")

		for i in range(0, max(len(vlist1), len(vlist2))):
			# Implcit .0 is given a value of -1, so that 1.0.0 > 1.0, since it
			# would be ambiguous if two versions that aren't literally equal
			# are given the same value (in sorting, for example).
			if len(vlist1) <= i or len(vlist1[i]) == 0:
				list1.append(-1)
				list2.append(int(vlist2[i]))
			elif len(vlist2) <= i or len(vlist2[i]) == 0:
				list1.append(int(vlist1[i]))
				list2.append(-1)
			# Let's make life easy and use integers unless we're forced to use floats
			elif (vlist1[i][0] != "0" and vlist2[i][0] != "0"):
				list1.append(int(vlist1[i]))
				list2.append(int(vlist2[i]))
			# now we have to use floats so 1.02 compares correctly against 1.1
			else:
				# list1.append(float("0."+vlist1[i]))
				# list2.append(float("0."+vlist2[i]))
				# Since python floats have limited range, we multiply both
				# floating point representations by a constant so that they are
				# transformed into whole numbers. This allows the practically
				# infinite range of a python int to be exploited. The
				# multiplication is done by padding both literal strings with
				# zeros as necessary to ensure equal length.
				max_len = max(len(vlist1[i]), len(vlist2[i]))
				list1.append(int(vlist1[i].ljust(max_len, "0")))
				list2.append(int(vlist2[i].ljust(max_len, "0")))

	# and now the final letter
	# NOTE: Behavior changed in r2309 (between portage-2.0.x and portage-2.1).
	# The new behavior is 12.2.5 > 12.2b which, depending on how you look at,
	# may seem counter-intuitive. However, if you really think about it, it
	# seems like it's probably safe to assume that this is the behavior that
	# is intended by anyone who would use versions such as these.
	if len(match1.group(5)):
		list1.append(ord(match1.group(5)))
	if len(match2.group(5)):
		list2.append(ord(match2.group(5)))

	for i in range(0, max(len(list1), len(list2))):
		if len(list1) <= i:
			return -1
		elif len(list2) <= i:
			return 1
		elif list1[i] != list2[i]:
			a = list1[i]
			b = list2[i]
			rval = (a > b) - (a < b)
			return rval

	# main version is equal, so now compare the _suffix part
	list1 = match1.group(6).split("_")[1:]
	list2 = match2.group(6).split("_")[1:]
	
	for i in range(0, max(len(list1), len(list2))):
		# Implicit _p0 is given a value of -1, so that 1 < 1_p0
		if len(list1) <= i:
			s1 = ("p","-1")
		else:
			s1 = suffix_regexp.match(list1[i]).groups()
		if len(list2) <= i:
			s2 = ("p","-1")
		else:
			s2 = suffix_regexp.match(list2[i]).groups()
		if s1[0] != s2[0]:
			a = suffix_value[s1[0]]
			b = suffix_value[s2[0]]
			rval = (a > b) - (a < b)
			return rval
		if s1[1] != s2[1]:
			# it's possible that the s(1|2)[1] == ''
			# in such a case, fudge it.
			try:
				r1 = int(s1[1])
			except ValueError:
				r1 = 0
			try:
				r2 = int(s2[1])
			except ValueError:
				r2 = 0
			rval = (r1 > r2) - (r1 < r2)
			if rval:
				return rval

	# the suffix part is equal to, so finally check the revision
	if match1.group(10):
		r1 = int(match1.group(10))
	else:
		r1 = 0
	if match2.group(10):
		r2 = int(match2.group(10))
	else:
		r2 = 0
	rval = (r1 > r2) - (r1 < r2)
	return rval
	
def pkgcmp(pkg1, pkg2):
	"""
	Compare 2 package versions created in pkgsplit format.

	Example usage:
		>>> from portage.versions import *
		>>> pkgcmp(pkgsplit('test-1.0-r1'),pkgsplit('test-1.2-r3'))
		-1
		>>> pkgcmp(pkgsplit('test-1.3'),pkgsplit('test-1.2-r3'))
		1

	@param pkg1: package to compare with
	@type pkg1: list (example: ['test', '1.0', 'r1'])
	@param pkg2: package to compare againts
	@type pkg2: list (example: ['test', '1.0', 'r1'])
	@rtype: None or integer
	@return: 
		1. None if package names are not the same
		2. 1 if pkg1 is greater than pkg2
		3. -1 if pkg1 is less than pkg2 
		4. 0 if pkg1 equals pkg2
	"""
	if pkg1[0] != pkg2[0]:
		return None
	return vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:]))

def _pkgsplit(mypkg, eapi=None):
	"""
	@param mypkg: pv
	@return:
	1. None if input is invalid.
	2. (pn, ver, rev) if input is pv
	"""
	m = _get_pv_re(_get_eapi_attrs(eapi)).match(mypkg)
	if m is None:
		return None

	if m.group('pn_inval') is not None:
		# package name appears to have a version-like suffix
		return None

	rev = m.group('rev')
	if rev is None:
		rev = '0'
	rev = 'r' + rev

	return  (m.group('pn'), m.group('ver'), rev) 

_cat_re = re.compile('^%s$' % _cat, re.UNICODE)
_missing_cat = 'null'

def catpkgsplit(mydata, silent=1, eapi=None):
	"""
	Takes a Category/Package-Version-Rev and returns a list of each.
	
	@param mydata: Data to split
	@type mydata: string 
	@param silent: suppress error messages
	@type silent: Boolean (integer)
	@rype: list
	@return:
	1.  If each exists, it returns [cat, pkgname, version, rev]
	2.  If cat is not specificed in mydata, cat will be "null"
	3.  if rev does not exist it will be '-r0'
	"""
	try:
		return mydata.cpv_split
	except AttributeError:
		pass
	mysplit = mydata.split('/', 1)
	p_split=None
	if len(mysplit)==1:
		cat = _missing_cat
		p_split = _pkgsplit(mydata, eapi=eapi)
	elif len(mysplit)==2:
		cat = mysplit[0]
		if _cat_re.match(cat) is not None:
			p_split = _pkgsplit(mysplit[1], eapi=eapi)
	if not p_split:
		return None
	retval = (cat, p_split[0], p_split[1], p_split[2])
	return retval

class _pkg_str(_unicode):
	"""
	This class represents a cpv. It inherits from str (unicode in python2) and
	has attributes that cache results for use by functions like catpkgsplit and
	cpv_getkey which are called frequently (especially in match_from_list).
	Instances are typically created in dbapi.cp_list() or the Atom contructor,
	and propagate from there. Generally, code that pickles these objects will
	manually convert them to a plain unicode object first.
	"""

	def __new__(cls, cpv, metadata=None, settings=None, eapi=None,
		repo=None, slot=None):
		return _unicode.__new__(cls, cpv)

	def __init__(self, cpv, metadata=None, settings=None, eapi=None,
		repo=None, slot=None):
		if not isinstance(cpv, _unicode):
			# Avoid TypeError from _unicode.__init__ with PyPy.
			cpv = _unicode_decode(cpv)
		_unicode.__init__(cpv)
		if metadata is not None:
			self.__dict__['_metadata'] = metadata
			slot = metadata.get('SLOT', slot)
			repo = metadata.get('repository', repo)
			eapi = metadata.get('EAPI', eapi)
		if settings is not None:
			self.__dict__['_settings'] = settings
		if eapi is not None:
			self.__dict__['eapi'] = eapi
		self.__dict__['cpv_split'] = catpkgsplit(cpv, eapi=eapi)
		if self.cpv_split is None:
			raise InvalidData(cpv)
		self.__dict__['cp'] = self.cpv_split[0] + '/' + self.cpv_split[1]
		if self.cpv_split[-1] == "r0" and cpv[-3:] != "-r0":
			self.__dict__['version'] = "-".join(self.cpv_split[2:-1])
		else:
			self.__dict__['version'] = "-".join(self.cpv_split[2:])
		# for match_from_list introspection
		self.__dict__['cpv'] = self
		if slot is not None:
			eapi_attrs = _get_eapi_attrs(eapi)
			slot_match = _get_slot_re(eapi_attrs).match(slot)
			if slot_match is None:
				# Avoid an InvalidAtom exception when creating SLOT atoms
				self.__dict__['slot'] = '0'
				self.__dict__['sub_slot'] = '0'
				self.__dict__['slot_invalid'] = slot
			else:
				if eapi_attrs.slot_operator:
					slot_split = slot.split("/")
					self.__dict__['slot'] = slot_split[0]
					if len(slot_split) > 1:
						self.__dict__['sub_slot'] = slot_split[1]
					else:
						self.__dict__['sub_slot'] = slot_split[0]
				else:
					self.__dict__['slot'] = slot
					self.__dict__['sub_slot'] = slot

		if repo is not None:
			repo = _gen_valid_repo(repo)
			if not repo:
				repo = _unknown_repo
			self.__dict__['repo'] = repo

	def __setattr__(self, name, value):
		raise AttributeError("_pkg_str instances are immutable",
			self.__class__, name, value)

	@property
	def stable(self):
		try:
			return self._stable
		except AttributeError:
			try:
				metadata = self._metadata
				settings = self._settings
			except AttributeError:
				raise AttributeError('stable')
			if not settings.local_config:
				# Since repoman uses different config instances for
				# different profiles, our local instance does not
				# refer to the correct profile.
				raise AssertionError('invalid context')
			stable = settings._isStable(self)
			self.__dict__['_stable'] = stable
			return stable

def pkgsplit(mypkg, silent=1, eapi=None):
	"""
	@param mypkg: either a pv or cpv
	@return:
	1. None if input is invalid.
	2. (pn, ver, rev) if input is pv
	3. (cp, ver, rev) if input is a cpv
	"""
	catpsplit = catpkgsplit(mypkg, eapi=eapi)
	if catpsplit is None:
		return None
	cat, pn, ver, rev = catpsplit
	if cat is _missing_cat and '/' not in mypkg:
		return (pn, ver, rev)
	else:
		return (cat + '/' + pn, ver, rev)

def cpv_getkey(mycpv, eapi=None):
	"""Calls catpkgsplit on a cpv and returns only the cp."""
	try:
		return mycpv.cp
	except AttributeError:
		pass
	mysplit = catpkgsplit(mycpv, eapi=eapi)
	if mysplit is not None:
		return mysplit[0] + '/' + mysplit[1]

	warnings.warn("portage.versions.cpv_getkey() " + \
		"called with invalid cpv: '%s'" % (mycpv,),
		DeprecationWarning, stacklevel=2)

	myslash = mycpv.split("/", 1)
	mysplit = _pkgsplit(myslash[-1], eapi=eapi)
	if mysplit is None:
		return None
	mylen = len(myslash)
	if mylen == 2:
		return myslash[0] + "/" + mysplit[0]
	else:
		return mysplit[0]

def cpv_getversion(mycpv, eapi=None):
	"""Returns the v (including revision) from an cpv."""
	try:
		return mycpv.version
	except AttributeError:
		pass
	cp = cpv_getkey(mycpv, eapi=eapi)
	if cp is None:
		return None
	return mycpv[len(cp+"-"):]

def cpv_sort_key(eapi=None):
	"""
	Create an object for sorting cpvs, to be used as the 'key' parameter
	in places like list.sort() or sorted(). This calls catpkgsplit() once for
	each cpv and caches the result. If a given cpv is invalid or two cpvs
	have different category/package names, then plain string (> and <)
	comparison is used.

	@rtype: key object for sorting
	@return: object for use as the 'key' parameter in places like
		list.sort() or sorted()
	"""

	split_cache = {}

	def cmp_cpv(cpv1, cpv2):

		split1 = split_cache.get(cpv1, False)
		if split1 is False:
			split1 = None
			try:
				split1 = cpv1.cpv
			except AttributeError:
				try:
					split1 = _pkg_str(cpv1, eapi=eapi)
				except InvalidData:
					pass
			split_cache[cpv1] = split1

		split2 = split_cache.get(cpv2, False)
		if split2 is False:
			split2 = None
			try:
				split2 = cpv2.cpv
			except AttributeError:
				try:
					split2 = _pkg_str(cpv2, eapi=eapi)
				except InvalidData:
					pass
			split_cache[cpv2] = split2

		if split1 is None or split2 is None or split1.cp != split2.cp:
			return (cpv1 > cpv2) - (cpv1 < cpv2)

		return vercmp(split1.version, split2.version)

	return cmp_sort_key(cmp_cpv)

def catsplit(mydep):
        return mydep.split("/", 1)

def best(mymatches, eapi=None):
	"""Accepts None arguments; assumes matches are valid."""
	if not mymatches:
		return ""
	if len(mymatches) == 1:
		return mymatches[0]
	bestmatch = mymatches[0]
	try:
		v2 = bestmatch.version
	except AttributeError:
		v2 = _pkg_str(bestmatch, eapi=eapi).version
	for x in mymatches[1:]:
		try:
			v1 = x.version
		except AttributeError:
			v1 = _pkg_str(x, eapi=eapi).version
		if vercmp(v1, v2) > 0:
			bestmatch = x
			v2 = v1
	return bestmatch
