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

__all__ = ['getmaskingreason']

import portage
from portage import os
from portage.const import USER_CONFIG_PATH
from portage.dep import Atom, match_from_list, _slot_separator, _repo_separator
from portage.exception import InvalidAtom
from portage.localization import _
from portage.repository.config import _gen_valid_repo
from portage.util import grablines, normalize_path
from portage.versions import catpkgsplit
from _emerge.Package import Package

def getmaskingreason(mycpv, metadata=None, settings=None,
	portdb=None, return_location=False, myrepo=None):
	"""
	If specified, the myrepo argument is assumed to be valid. This
	should be a safe assumption since portdbapi methods always
	return valid repo names and valid "repository" metadata from
	aux_get.
	"""
	if settings is None:
		settings = portage.settings
	if portdb is None:
		portdb = portage.portdb
	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
		else:
			if myrepo is None:
				myrepo = _gen_valid_repo(metadata["repository"])

	elif myrepo is None:
		myrepo = metadata.get("repository")
		if myrepo is not None:
			myrepo = _gen_valid_repo(metadata["repository"])

	if metadata is not None and \
		not portage.eapi_is_supported(metadata["EAPI"]):
		# Return early since otherwise we might produce invalid
		# results given that the EAPI is not supported. Also,
		# metadata is mostly useless in this case since it doesn't
		# contain essential things like SLOT.
		if return_location:
			return (None, None)
		else:
			return None

	# Sometimes we can't access SLOT or repository due to corruption.
	pkg = mycpv
	if metadata is not None:
		pkg = "".join((mycpv, _slot_separator, metadata["SLOT"]))
	# At this point myrepo should be None, a valid name, or
	# Package.UNKNOWN_REPO which we ignore.
	if myrepo is not None and myrepo != Package.UNKNOWN_REPO:
		pkg = "".join((pkg, _repo_separator, myrepo))
	cpv_slot_list = [pkg]

	mycp=mysplit[0]+"/"+mysplit[1]

	# XXX- This is a temporary duplicate of code from the config constructor.
	locations = [os.path.join(settings["PORTDIR"], "profiles")]
	locations.extend(settings.profiles)
	for ov in settings["PORTDIR_OVERLAY"].split():
		profdir = os.path.join(normalize_path(ov), "profiles")
		if os.path.isdir(profdir):
			locations.append(profdir)
	locations.append(os.path.join(settings["PORTAGE_CONFIGROOT"],
		USER_CONFIG_PATH))
	locations.reverse()
	pmasklists = []
	for profile in locations:
		pmask_filename = os.path.join(profile, "package.mask")
		pmasklists.append((pmask_filename, grablines(pmask_filename, recursive=1)))

	pmaskdict = settings._mask_manager._pmaskdict
	if mycp in pmaskdict:
		for x in pmaskdict[mycp]:
			if match_from_list(x, cpv_slot_list):
				x = x.without_repo
				for pmask in pmasklists:
					comment = ""
					comment_valid = -1
					pmask_filename = pmask[0]
					for i in range(len(pmask[1])):
						l = pmask[1][i].strip()
						try:
							l_atom = Atom(l, allow_repo=True,
								allow_wildcard=True).without_repo
						except InvalidAtom:
							l_atom = None
						if l == "":
							comment = ""
							comment_valid = -1
						elif l[0] == "#":
							comment += (l+"\n")
							comment_valid = i + 1
						elif l_atom == x:
							if comment_valid != i:
								comment = ""
							if return_location:
								return (comment, pmask_filename)
							else:
								return comment
						elif comment_valid != -1:
							# Apparently this comment applies to multiple masks, so
							# it remains valid until a blank line is encountered.
							comment_valid += 1
	if return_location:
		return (None, None)
	else:
		return None
