# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

__all__ = ['getmaskingstatus']

import sys

import portage
from portage import eapi_is_supported, _eapi_is_deprecated
from portage.dep import match_from_list, _slot_separator, _repo_separator
from portage.localization import _
from portage.package.ebuild.config import config
from portage.versions import catpkgsplit, cpv_getkey
from _emerge.Package import Package

if sys.hexversion >= 0x3000000:
	basestring = str

class _UnmaskHint(object):

	__slots__ = ('key', 'value')

	def __init__(self, key, value):
		self.key = key
		self.value = value

class _MaskReason(object):

	__slots__ = ('category', 'message', 'unmask_hint')

	def __init__(self, category, message, unmask_hint=None):
		self.category = category
		self.message = message
		self.unmask_hint = unmask_hint

def getmaskingstatus(mycpv, settings=None, portdb=None, myrepo=None):
	if settings is None:
		settings = config(clone=portage.settings)
	if portdb is None:
		portdb = portage.portdb

	return [mreason.message for \
		mreason in _getmaskingstatus(mycpv, settings, portdb,myrepo)]

def _getmaskingstatus(mycpv, settings, portdb, myrepo=None):

	metadata = None
	installed = False
	if not isinstance(mycpv, basestring):
		# emerge passed in a Package instance
		pkg = mycpv
		mycpv = pkg.cpv
		metadata = pkg.metadata
		installed = pkg.installed

	mysplit = catpkgsplit(mycpv)
	if not mysplit:
		raise ValueError(_("invalid CPV: %s") % mycpv)
	if metadata is None:
		db_keys = list(portdb._aux_cache_keys)
		try:
			metadata = dict(zip(db_keys, portdb.aux_get(mycpv, db_keys, myrepo=myrepo)))
		except KeyError:
			if not portdb.cpv_exists(mycpv):
				raise
			return [_MaskReason("corruption", "corruption")]
		if "?" in metadata["LICENSE"]:
			settings.setcpv(mycpv, mydb=metadata)
			metadata["USE"] = settings["PORTAGE_USE"]
		else:
			metadata["USE"] = ""

	rValue = []

	# package.mask checking
	if settings._getMaskAtom(mycpv, metadata):
		rValue.append(_MaskReason("package.mask", "package.mask", _UnmaskHint("p_mask", None)))

	# keywords checking
	eapi = metadata["EAPI"]
	mygroups = settings._getKeywords(mycpv, metadata)
	licenses = metadata["LICENSE"]
	properties = metadata["PROPERTIES"]
	if eapi.startswith("-"):
		eapi = eapi[1:]
	if not eapi_is_supported(eapi):
		return [_MaskReason("EAPI", "EAPI %s" % eapi)]
	elif _eapi_is_deprecated(eapi) and not installed:
		return [_MaskReason("EAPI", "EAPI %s" % eapi)]
	egroups = settings.configdict["backupenv"].get(
		"ACCEPT_KEYWORDS", "").split()
	global_accept_keywords = settings.get("ACCEPT_KEYWORDS", "")
	pgroups = global_accept_keywords.split()
	myarch = settings["ARCH"]
	if pgroups and myarch not in pgroups:
		"""For operating systems other than Linux, ARCH is not necessarily a
		valid keyword."""
		myarch = pgroups[0].lstrip("~")

	# NOTE: This logic is copied from KeywordsManager.getMissingKeywords().
	unmaskgroups = settings._keywords_manager.getPKeywords(mycpv,
		metadata["SLOT"], metadata["repository"], global_accept_keywords)
	pgroups.extend(unmaskgroups)
	if unmaskgroups or egroups:
		pgroups = settings._keywords_manager._getEgroups(egroups, pgroups)
	else:
		pgroups = set(pgroups)

	kmask = "missing"
	kmask_hint = None

	if '**' in pgroups:
		kmask = None
	else:
		for keyword in pgroups:
			if keyword in mygroups:
				kmask = None
				break

	if kmask:
		for gp in mygroups:
			if gp=="*":
				kmask=None
				break
			elif gp=="-"+myarch and myarch in pgroups:
				kmask="-"+myarch
				break
			elif gp=="~"+myarch and myarch in pgroups:
				kmask="~"+myarch
				kmask_hint = _UnmaskHint("unstable keyword", kmask)
				break

	if kmask == "missing":
		kmask_hint = _UnmaskHint("unstable keyword", "**")

	try:
		missing_licenses = settings._getMissingLicenses(mycpv, metadata)
		if missing_licenses:
			allowed_tokens = set(["||", "(", ")"])
			allowed_tokens.update(missing_licenses)
			license_split = licenses.split()
			license_split = [x for x in license_split \
				if x in allowed_tokens]
			msg = license_split[:]
			msg.append("license(s)")
			rValue.append(_MaskReason("LICENSE", " ".join(msg), _UnmaskHint("license", set(missing_licenses))))
	except portage.exception.InvalidDependString as e:
		rValue.append(_MaskReason("invalid", "LICENSE: "+str(e)))

	try:
		missing_properties = settings._getMissingProperties(mycpv, metadata)
		if missing_properties:
			allowed_tokens = set(["||", "(", ")"])
			allowed_tokens.update(missing_properties)
			properties_split = properties.split()
			properties_split = [x for x in properties_split \
					if x in allowed_tokens]
			msg = properties_split[:]
			msg.append("properties")
			rValue.append(_MaskReason("PROPERTIES", " ".join(msg)))
	except portage.exception.InvalidDependString as e:
		rValue.append(_MaskReason("invalid", "PROPERTIES: "+str(e)))

	# Only show KEYWORDS masks for installed packages
	# if they're not masked for any other reason.
	if kmask and (not installed or not rValue):
		rValue.append(_MaskReason("KEYWORDS",
			kmask + " keyword", unmask_hint=kmask_hint))

	return rValue
