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

from __future__ import unicode_literals

__all__ = ['getmaskingstatus']

import sys

import portage
from portage import eapi_is_supported, _eapi_is_deprecated
from portage.exception import InvalidDependString
from portage.localization import _
from portage.package.ebuild.config import config
from portage.versions import catpkgsplit, _pkg_str

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

	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"] = ""

	try:
		mycpv.slot
	except AttributeError:
		try:
			mycpv = _pkg_str(mycpv, metadata=metadata, settings=settings)
		except portage.exception.InvalidData:
			raise ValueError(_("invalid CPV: %s") % mycpv)

	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"]
	restrict = metadata["RESTRICT"]
	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 == "~*":
				for x in pgroups:
					if x[:1] == "~":
						kmask = None
						break
				if kmask is 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)))

	try:
		missing_restricts = settings._getMissingRestrict(mycpv, metadata)
		if missing_restricts:
			msg = list(missing_restricts)
			msg.append("in RESTRICT")
			rValue.append(_MaskReason("RESTRICT", " ".join(msg)))
	except InvalidDependString as e:
		rValue.append(_MaskReason("invalid", "RESTRICT: %s" % (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
