#!/usr/bin/python -bO
# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from __future__ import print_function, unicode_literals

import signal
import sys
# This block ensures that ^C interrupts are handled quietly.
try:

	def exithandler(signum, _frame):
		signal.signal(signal.SIGINT, signal.SIG_IGN)
		signal.signal(signal.SIGTERM, signal.SIG_IGN)
		sys.exit(128 + signum)

	signal.signal(signal.SIGINT, exithandler)
	signal.signal(signal.SIGTERM, exithandler)

except KeyboardInterrupt:
	sys.exit(128 + signal.SIGINT)

import os
import types

# Avoid sandbox violations after python upgrade.
pym_path = os.path.join(os.path.dirname(
	os.path.dirname(os.path.realpath(__file__))), "pym")
if os.environ.get("SANDBOX_ON") == "1":
	sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
	if pym_path not in sandbox_write:
		sandbox_write.append(pym_path)
		os.environ["SANDBOX_WRITE"] = \
			":".join(filter(None, sandbox_write))
	del sandbox_write

sys.path.insert(0, pym_path)
import portage
portage._internal_caller = True
from portage import os
from portage.eapi import eapi_has_repo_deps
from portage.util import writemsg, writemsg_stdout
from portage.util._argparse import ArgumentParser
portage.proxy.lazyimport.lazyimport(globals(),
	're',
	'subprocess',
	'_emerge.Package:Package',
	'_emerge.RootConfig:RootConfig',
	'_emerge.is_valid_package_atom:insert_category_into_atom',
	'portage.dbapi._expand_new_virt:expand_new_virt',
	'portage._sets.base:InternalPackageSet',
	'portage.xml.metadata:MetaDataXML'
)

def eval_atom_use(atom):
	if 'USE' in os.environ:
		use = frozenset(os.environ['USE'].split())
		atom = atom.evaluate_conditionals(use)
	return atom

def uses_eroot(function):
	function.uses_eroot = True
	return function

#-----------------------------------------------------------------------------
#
# To add functionality to this tool, add a function below.
#
# The format for functions is:
#
#   def function(argv):
#       """<list of options for this function>
#       <description of the function>
#       """
#       <code>
#
# "argv" is an array of the command line parameters provided after the command.
#
# Make sure you document the function in the right format.  The documentation
# is used to display help on the function.
#
# You do not need to add the function to any lists, this tool is introspective,
# and will automaticly add a command by the same name as the function!
#

@uses_eroot
def has_version(argv):
	"""<eroot> <category/package>
	Return code 0 if it's available, 1 otherwise.
	"""
	if (len(argv) < 2):
		print("ERROR: insufficient parameters!")
		return 3

	warnings = []

	allow_repo = atom_validate_strict is False or eapi_has_repo_deps(eapi)
	try:
		atom = portage.dep.Atom(argv[1], allow_repo=allow_repo)
	except portage.exception.InvalidAtom:
		if atom_validate_strict:
			portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
				noiselevel=-1)
			return 2
		else:
			atom = argv[1]
	else:
		if atom_validate_strict:
			try:
				atom = portage.dep.Atom(argv[1], allow_repo=allow_repo, eapi=eapi)
			except portage.exception.InvalidAtom as e:
				warnings.append("QA Notice: %s: %s" % ('has_version', e))
		atom = eval_atom_use(atom)

	if warnings:
		elog('eqawarn', warnings)

	try:
		mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
		if mylist:
			return 0
		else:
			return 1
	except KeyError:
		return 1
	except portage.exception.InvalidAtom:
		portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
			noiselevel=-1)
		return 2


@uses_eroot
def best_version(argv):
	"""<eroot> <category/package>
	Returns category/package-version (without .ebuild).
	"""
	if (len(argv) < 2):
		print("ERROR: insufficient parameters!")
		return 3

	warnings = []

	allow_repo = atom_validate_strict is False or eapi_has_repo_deps(eapi)
	try:
		atom = portage.dep.Atom(argv[1], allow_repo=allow_repo)
	except portage.exception.InvalidAtom:
		if atom_validate_strict:
			portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
				noiselevel=-1)
			return 2
		else:
			atom = argv[1]
	else:
		if atom_validate_strict:
			try:
				atom = portage.dep.Atom(argv[1], allow_repo=allow_repo, eapi=eapi)
			except portage.exception.InvalidAtom as e:
				warnings.append("QA Notice: %s: %s" % ('best_version', e))
		atom = eval_atom_use(atom)

	if warnings:
		elog('eqawarn', warnings)

	try:
		mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
		print(portage.best(mylist))
	except KeyError:
		return 1


@uses_eroot
def mass_best_version(argv):
	"""<eroot> [<category/package>]+
	Returns category/package-version (without .ebuild).
	"""
	if (len(argv) < 2):
		print("ERROR: insufficient parameters!")
		return 2
	try:
		for pack in argv[1:]:
			mylist = portage.db[argv[0]]['vartree'].dbapi.match(pack)
			print('%s:%s' % (pack, portage.best(mylist)))
	except KeyError:
		return 1


@uses_eroot
def metadata(argv):
	if (len(argv) < 4):
		print('ERROR: insufficient parameters!', file=sys.stderr)
		return 2

	eroot, pkgtype, pkgspec = argv[0:3]
	metakeys = argv[3:]
	type_map = {
		'ebuild': 'porttree',
		'binary': 'bintree',
		'installed': 'vartree'
	}
	if pkgtype not in type_map:
		print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr)
		return 1
	trees = portage.db
	repo = portage.dep.dep_getrepo(pkgspec)
	pkgspec = portage.dep.remove_slot(pkgspec)
	try:
		values = trees[eroot][type_map[pkgtype]].dbapi.aux_get(
			pkgspec, metakeys, myrepo=repo)
		writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
	except KeyError:
		print("Package not found: '%s'" % pkgspec, file=sys.stderr)
		return 1

metadata.__doc__ = """
<eroot> <pkgtype> <category/package> [<key>]+
Returns metadata values for the specified package.
Available keys: %s
"""  % ','.join(sorted(x for x in portage.auxdbkeys \
if not x.startswith('UNUSED_')))


@uses_eroot
def contents(argv):
	"""<eroot> <category/package>
	List the files that are installed for a given package, with
	one file listed on each line. All file names will begin with
	<eroot>.
	"""
	if len(argv) != 2:
		print("ERROR: expected 2 parameters, got %d!" % len(argv))
		return 2

	root, cpv = argv
	vartree = portage.db[root]["vartree"]
	if not vartree.dbapi.cpv_exists(cpv):
		sys.stderr.write("Package not found: '%s'\n" % cpv)
		return 1
	cat, pkg = portage.catsplit(cpv)
	db = portage.dblink(cat, pkg, root, vartree.settings,
		treetype="vartree", vartree=vartree)
	writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
		noiselevel=-1)


@uses_eroot
def owners(argv):
	"""<eroot> [<filename>]+
	Given a list of files, print the packages that own the files and which
	files belong to each package. Files owned by a package are listed on
	the lines below it, indented by a single tab character (\\t). All file
	paths must either start with <eroot> or be a basename alone.
	Returns 1 if no owners could be found, and 0 otherwise.
	"""
	if len(argv) < 2:
		sys.stderr.write("ERROR: insufficient parameters!\n")
		sys.stderr.flush()
		return 2

	eroot = argv[0]
	vardb = portage.db[eroot]["vartree"].dbapi
	root = portage.settings['ROOT']

	cwd = None
	try:
		cwd = os.getcwd()
	except OSError:
		pass

	files = []
	orphan_abs_paths = set()
	orphan_basenames = set()
	for f in argv[1:]:
		f = portage.normalize_path(f)
		is_basename = os.sep not in f
		if not is_basename and f[:1] != os.sep:
			if cwd is None:
				sys.stderr.write("ERROR: cwd does not exist!\n")
				sys.stderr.flush()
				return 2
			f = os.path.join(cwd, f)
			f = portage.normalize_path(f)
		if not is_basename and not f.startswith(eroot):
			sys.stderr.write("ERROR: file paths must begin with <eroot>!\n")
			sys.stderr.flush()
			return 2
		if is_basename:
			files.append(f)
			orphan_basenames.add(f)
		else:
			files.append(f[len(root)-1:])
			orphan_abs_paths.add(f)

	owners = vardb._owners.get_owners(files)

	msg = []
	for pkg, owned_files in owners.items():
		cpv = pkg.mycpv
		msg.append("%s\n" % cpv)
		for f in sorted(owned_files):
			f_abs = os.path.join(root, f.lstrip(os.path.sep))
			msg.append("\t%s\n" % (f_abs,))
			orphan_abs_paths.discard(f_abs)
			if orphan_basenames:
				orphan_basenames.discard(os.path.basename(f_abs))

	writemsg_stdout(''.join(msg), noiselevel=-1)

	if orphan_abs_paths or orphan_basenames:
		orphans = []
		orphans.extend(orphan_abs_paths)
		orphans.extend(orphan_basenames)
		orphans.sort()
		msg = []
		msg.append("None of the installed packages claim these files:\n")
		for f in orphans:
			msg.append("\t%s\n" % (f,))
		sys.stderr.write("".join(msg))
		sys.stderr.flush()

	if owners:
		return 0
	return 1


@uses_eroot
def is_protected(argv):
	"""<eroot> <filename>
	Given a single filename, return code 0 if it's protected, 1 otherwise.
	The filename must begin with <eroot>.
	"""
	if len(argv) != 2:
		sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
		sys.stderr.flush()
		return 2

	root, filename = argv

	err = sys.stderr
	cwd = None
	try:
		cwd = os.getcwd()
	except OSError:
		pass

	f = portage.normalize_path(filename)
	if not f.startswith(os.path.sep):
		if cwd is None:
			err.write("ERROR: cwd does not exist!\n")
			err.flush()
			return 2
		f = os.path.join(cwd, f)
		f = portage.normalize_path(f)

	if not f.startswith(root):
		err.write("ERROR: file paths must begin with <eroot>!\n")
		err.flush()
		return 2

	from portage.util import ConfigProtect

	settings = portage.settings
	protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
	protect_mask = portage.util.shlex_split(
		settings.get("CONFIG_PROTECT_MASK", ""))
	protect_obj = ConfigProtect(root, protect, protect_mask)

	if protect_obj.isprotected(f):
		return 0
	return 1


@uses_eroot
def filter_protected(argv):
	"""<eroot>
	Read filenames from stdin and write them to stdout if they are protected.
	All filenames are delimited by \\n and must begin with <eroot>.
	"""
	if len(argv) != 1:
		sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv))
		sys.stderr.flush()
		return 2

	root, = argv
	out = sys.stdout
	err = sys.stderr
	cwd = None
	try:
		cwd = os.getcwd()
	except OSError:
		pass

	from portage.util import ConfigProtect

	settings = portage.settings
	protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
	protect_mask = portage.util.shlex_split(
		settings.get("CONFIG_PROTECT_MASK", ""))
	protect_obj = ConfigProtect(root, protect, protect_mask)

	errors = 0

	for line in sys.stdin:
		filename = line.rstrip("\n")
		f = portage.normalize_path(filename)
		if not f.startswith(os.path.sep):
			if cwd is None:
				err.write("ERROR: cwd does not exist!\n")
				err.flush()
				errors += 1
				continue
			f = os.path.join(cwd, f)
			f = portage.normalize_path(f)

		if not f.startswith(root):
			err.write("ERROR: file paths must begin with <eroot>!\n")
			err.flush()
			errors += 1
			continue

		if protect_obj.isprotected(f):
			out.write("%s\n" % filename)
	out.flush()

	if errors:
		return 2

	return 0


@uses_eroot
def best_visible(argv):
	"""<eroot> [pkgtype] <atom>
	Returns category/package-version (without .ebuild).
	The pkgtype argument defaults to "ebuild" if unspecified,
	otherwise it must be one of ebuild, binary, or installed.
	"""
	if (len(argv) < 2):
		writemsg("ERROR: insufficient parameters!\n", noiselevel=-1)
		return 2

	pkgtype = "ebuild"
	if len(argv) > 2:
		pkgtype = argv[1]
		atom = argv[2]
	else:
		atom = argv[1]

	type_map = {
		"ebuild":"porttree",
		"binary":"bintree",
		"installed":"vartree"}

	if pkgtype not in type_map:
		writemsg("Unrecognized package type: '%s'\n" % pkgtype,
			noiselevel=-1)
		return 2

	eroot = argv[0]
	db = portage.db[eroot][type_map[pkgtype]].dbapi

	try:
		atom = portage.dep_expand(atom, mydb=db, settings=portage.settings)
	except portage.exception.InvalidAtom:
		writemsg("ERROR: Invalid atom: '%s'\n" % atom,
			noiselevel=-1)
		return 2

	root_config = RootConfig(portage.settings, portage.db[eroot], None)

	if hasattr(db, "xmatch"):
		cpv_list = db.xmatch("match-all-cpv-only", atom)
	else:
		cpv_list = db.match(atom)

	if cpv_list:
		# reversed, for descending order
		cpv_list.reverse()
		# verify match, since the atom may match the package
		# for a given cpv from one repo but not another, and
		# we can use match-all-cpv-only to avoid redundant
		# metadata access.
		atom_set = InternalPackageSet(initial_atoms=(atom,))

		if atom.repo is None and hasattr(db, "getRepositories"):
			repo_list = db.getRepositories()
		else:
			repo_list = [atom.repo]

		for cpv in cpv_list:
			for repo in repo_list:
				try:
					metadata = dict(zip(Package.metadata_keys,
						db.aux_get(cpv, Package.metadata_keys, myrepo=repo)))
				except KeyError:
					continue
				pkg = Package(built=(pkgtype != "ebuild"), cpv=cpv,
					installed=(pkgtype=="installed"), metadata=metadata,
					root_config=root_config, type_name=pkgtype)
				if not atom_set.findAtomForPackage(pkg):
					continue

				if pkg.visible:
					writemsg_stdout("%s\n" % (pkg.cpv,), noiselevel=-1)
					return os.EX_OK

	# No package found, write out an empty line.
	writemsg_stdout("\n", noiselevel=-1)

	return 1


@uses_eroot
def mass_best_visible(argv):
	"""<eroot> [<type>] [<category/package>]+
	Returns category/package-version (without .ebuild).
	The pkgtype argument defaults to "ebuild" if unspecified,
	otherwise it must be one of ebuild, binary, or installed.
	"""
	type_map = {
		"ebuild":"porttree",
		"binary":"bintree",
		"installed":"vartree"}

	if (len(argv) < 2):
		print("ERROR: insufficient parameters!")
		return 2
	try:
		root = argv.pop(0)
		pkgtype = "ebuild"
		if argv[0] in type_map:
			pkgtype = argv.pop(0)
		for pack in argv:
			writemsg_stdout("%s:" % pack, noiselevel=-1)
			best_visible([root, pkgtype, pack])
	except KeyError:
		return 1


@uses_eroot
def all_best_visible(argv):
	"""<eroot>
	Returns all best_visible packages (without .ebuild).
	"""
	if len(argv) < 1:
		sys.stderr.write("ERROR: insufficient parameters!\n")
		sys.stderr.flush()
		return 2

	#print portage.db[argv[0]]["porttree"].dbapi.cp_all()
	for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
		mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
		if mybest:
			print(mybest)


@uses_eroot
def match(argv):
	"""<eroot> <atom>
	Returns a \\n separated list of category/package-version.
	When given an empty string, all installed packages will
	be listed.
	"""
	if len(argv) != 2:
		print("ERROR: expected 2 parameters, got %d!" % len(argv))
		return 2
	root, atom = argv
	if not atom:
		atom = "*/*"

	vardb = portage.db[root]["vartree"].dbapi
	try:
		atom = portage.dep.Atom(atom, allow_wildcard=True, allow_repo=True)
	except portage.exception.InvalidAtom:
		# maybe it's valid but missing category
		atom = portage.dep_expand(atom, mydb=vardb, settings=vardb.settings)

	if atom.extended_syntax:
		if atom == "*/*":
			results = vardb.cpv_all()
		else:
			results = []
			require_metadata = atom.slot or atom.repo
			for cpv in vardb.cpv_all():

				if not portage.match_from_list(atom, [cpv]):
					continue

				if require_metadata:
					try:
						cpv = vardb._pkg_str(cpv, atom.repo)
					except (KeyError, portage.exception.InvalidData):
						continue
					if not portage.match_from_list(atom, [cpv]):
						continue

				results.append(cpv)

		results.sort()
	else:
		results = vardb.match(atom)
	for cpv in results:
		print(cpv)


@uses_eroot
def expand_virtual(argv):
	"""<eroot> <atom>
	Returns a \\n separated list of atoms expanded from a
	given virtual atom (GLEP 37 virtuals only),
	excluding blocker atoms. Satisfied
	virtual atoms are not included in the output, since
	they are expanded to real atoms which are displayed.
	Unsatisfied virtual atoms are displayed without
	any expansion. The "match" command can be used to
	resolve the returned atoms to specific installed
	packages.
	"""
	if len(argv) != 2:
		writemsg("ERROR: expected 2 parameters, got %d!\n" % len(argv),
			noiselevel=-1)
		return 2

	root, atom = argv

	try:
		results = list(expand_new_virt(
			portage.db[root]["vartree"].dbapi, atom))
	except portage.exception.InvalidAtom:
		writemsg("ERROR: Invalid atom: '%s'\n" % atom,
			noiselevel=-1)
		return 2

	results.sort()
	for x in results:
		if not x.blocker:
			writemsg_stdout("%s\n" % (x,))

	return os.EX_OK


def vdb_path(_argv):
	"""
	Returns the path used for the var(installed) package database for the
	set environment/configuration options.
	"""
	out = sys.stdout
	out.write(os.path.join(portage.settings["EROOT"], portage.VDB_PATH) + "\n")
	out.flush()
	return os.EX_OK

def gentoo_mirrors(_argv):
	"""
	Returns the mirrors set to use in the portage configuration.
	"""
	print(portage.settings["GENTOO_MIRRORS"])


@uses_eroot
def repositories_configuration(argv):
	"""<eroot>
	Returns the configuration of repositories.
	"""
	if len(argv) < 1:
		print("ERROR: insufficient parameters!", file=sys.stderr)
		return 3
	sys.stdout.write(portage.db[argv[0]]["vartree"].settings.repositories.config_string())
	sys.stdout.flush()

@uses_eroot
def repos_config(argv):
	"""
	<eroot>
	This is an alias for the repositories_configuration command.
	"""
	return repositories_configuration(argv)

def portdir(_argv):
	"""
	Returns the PORTDIR path.
	Deprecated in favor of repositories_configuration command.
	"""
	print("WARNING: 'portageq portdir' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
	print(portage.settings["PORTDIR"])


def config_protect(_argv):
	"""
	Returns the CONFIG_PROTECT paths.
	"""
	print(portage.settings["CONFIG_PROTECT"])


def config_protect_mask(_argv):
	"""
	Returns the CONFIG_PROTECT_MASK paths.
	"""
	print(portage.settings["CONFIG_PROTECT_MASK"])


def portdir_overlay(_argv):
	"""
	Returns the PORTDIR_OVERLAY path.
	Deprecated in favor of repositories_configuration command.
	"""
	print("WARNING: 'portageq portdir_overlay' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
	print(portage.settings["PORTDIR_OVERLAY"])


def pkgdir(_argv):
	"""
	Returns the PKGDIR path.
	"""
	print(portage.settings["PKGDIR"])


def distdir(_argv):
	"""
	Returns the DISTDIR path.
	"""
	print(portage.settings["DISTDIR"])


def colormap(_argv):
	"""
	Display the color.map as environment variables.
	"""
	print(portage.output.colormap())


def envvar(argv):
	"""<variable>+
	Returns a specific environment variable as exists prior to ebuild.sh.
	Similar to: emerge --verbose --info | egrep '^<variable>='
	"""
	verbose = "-v" in argv
	if verbose:
		argv.pop(argv.index("-v"))

	if len(argv) == 0:
		print("ERROR: insufficient parameters!")
		return 2

	for arg in argv:
		if arg in ("PORTDIR", "PORTDIR_OVERLAY", "SYNC"):
			print("WARNING: 'portageq envvar %s' is deprecated. Use 'portageq repositories_configuration' instead." % arg, file=sys.stderr)
		if verbose:
			print(arg + "=" + portage._shell_quote(portage.settings[arg]))
		else:
			print(portage.settings[arg])


@uses_eroot
def get_repos(argv):
	"""<eroot>
	Returns all repos with names (repo_name file) argv[0] = $EROOT
	"""
	if len(argv) < 1:
		print("ERROR: insufficient parameters!")
		return 2
	print(" ".join(reversed(portage.db[argv[0]]["vartree"].settings.repositories.prepos_order)))


@uses_eroot
def master_repositories(argv):
	"""<eroot> <repo_id>+
	Returns space-separated list of master repositories for specified repository.
	"""
	if len(argv) < 2:
		print("ERROR: insufficient parameters!", file=sys.stderr)
		return 3
	for arg in argv[1:]:
		if portage.dep._repo_name_re.match(arg) is None:
			print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
			return 2
		try:
			repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
		except KeyError:
			print("")
			return 1
		else:
			print(" ".join(x.name for x in repo.masters))

@uses_eroot
def master_repos(argv):
	"""<eroot> <repo_id>+
	This is an alias for the master_repositories command.
	"""
	return master_repositories(argv)

@uses_eroot
def get_repo_path(argv):
	"""<eroot> <repo_id>+
	Returns the path to the repo named argv[1], argv[0] = $EROOT
	"""
	if len(argv) < 2:
		print("ERROR: insufficient parameters!", file=sys.stderr)
		return 3
	for arg in argv[1:]:
		if portage.dep._repo_name_re.match(arg) is None:
			print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
			return 2
		path = portage.db[argv[0]]["vartree"].settings.repositories.treemap.get(arg)
		if path is None:
			print("")
			return 1
		print(path)


@uses_eroot
def available_eclasses(argv):
	"""<eroot> <repo_id>+
	Returns space-separated list of available eclasses for specified repository.
	"""
	if len(argv) < 2:
		print("ERROR: insufficient parameters!", file=sys.stderr)
		return 3
	for arg in argv[1:]:
		if portage.dep._repo_name_re.match(arg) is None:
			print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
			return 2
		try:
			repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
		except KeyError:
			print("")
			return 1
		else:
			print(" ".join(sorted(repo.eclass_db.eclasses)))


@uses_eroot
def eclass_path(argv):
	"""<eroot> <repo_id> <eclass>+
	Returns the path to specified eclass for specified repository.
	"""
	if len(argv) < 3:
		print("ERROR: insufficient parameters!", file=sys.stderr)
		return 3
	if portage.dep._repo_name_re.match(argv[1]) is None:
		print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
		return 2
	try:
		repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
	except KeyError:
		print("")
		return 1
	else:
		retval = 0
		for arg in argv[2:]:
			try:
				eclass = repo.eclass_db.eclasses[arg]
			except KeyError:
				print("")
				retval = 1
			else:
				print(eclass.location)
		return retval


@uses_eroot
def license_path(argv):
	"""<eroot> <repo_id> <license>+
	Returns the path to specified license for specified repository.
	"""
	if len(argv) < 3:
		print("ERROR: insufficient parameters!", file=sys.stderr)
		return 3
	if portage.dep._repo_name_re.match(argv[1]) is None:
		print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
		return 2
	try:
		repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
	except KeyError:
		print("")
		return 1
	else:
		retval = 0
		for arg in argv[2:]:
			eclass_path = ""
			paths = reversed([os.path.join(x.location, 'licenses', arg) for x in list(repo.masters) + [repo]])
			for path in paths:
				if os.path.exists(path):
					eclass_path = path
					break
			if eclass_path == "":
				retval = 1
			print(eclass_path)
		return retval


@uses_eroot
def list_preserved_libs(argv):
	"""<eroot>
	Print a list of libraries preserved during a package update in the form
	package: path. Returns 1 if no preserved libraries could be found,
	0 otherwise.
	"""

	if len(argv) != 1:
		print("ERROR: wrong number of arguments")
		return 2
	mylibs = portage.db[argv[0]]["vartree"].dbapi._plib_registry.getPreservedLibs()
	rValue = 1
	msg = []
	for cpv in sorted(mylibs):
		msg.append(cpv)
		for path in mylibs[cpv]:
			msg.append(' ' + path)
			rValue = 0
		msg.append('\n')
	writemsg_stdout(''.join(msg), noiselevel=-1)
	return rValue


class MaintainerEmailMatcher(object):
	def __init__(self, maintainer_emails):
		self._re = re.compile("^(%s)$" % "|".join(maintainer_emails))

	def __call__(self, metadata_xml):
		match = False
		matcher = self._re.match
		for x in metadata_xml.maintainers():
			if x.email is not None and matcher(x.email) is not None:
				match = True
				break
		return match

class HerdMatcher(object):
	def __init__(self, herds):
		self._herds = frozenset(herds)

	def __call__(self, metadata_xml):
		herds = self._herds
		return any(x in herds for x in metadata_xml.herds())


def pquery(parser, opts, args):
	"""[options] [atom]+
	Emulates a subset of Pkgcore's pquery tool.
	"""

	portdb = portage.db[portage.root]['porttree'].dbapi
	root_config = RootConfig(portdb.settings,
		portage.db[portage.root], None)

	def _pkg(cpv, repo_name):
		try:
			metadata = dict(zip(
				Package.metadata_keys,
				portdb.aux_get(cpv,
				Package.metadata_keys,
				myrepo=repo_name)))
		except KeyError:
			raise portage.exception.PackageNotFound(cpv)
		return Package(built=False, cpv=cpv,
			installed=False, metadata=metadata,
			root_config=root_config,
			type_name="ebuild")

	need_metadata = False
	atoms = []
	for arg in args:
		if "/" not in arg.split(":")[0]:
			atom = insert_category_into_atom(arg, '*')
			if atom is None:
				writemsg("ERROR: Invalid atom: '%s'\n" % arg,
					noiselevel=-1)
				return 2
		else:
			atom = arg

		try:
			atom = portage.dep.Atom(atom, allow_wildcard=True, allow_repo=True)
		except portage.exception.InvalidAtom:
			writemsg("ERROR: Invalid atom: '%s'\n" % arg,
				noiselevel=-1)
			return 2

		if atom.slot is not None:
			need_metadata = True

		atoms.append(atom)

	if "*/*" in atoms:
		del atoms[:]
		need_metadata = False

	if not opts.no_filters:
		need_metadata = True

	xml_matchers = []
	if opts.maintainer_email:
		maintainer_emails = []
		for x in opts.maintainer_email:
			maintainer_emails.extend(x.split(","))
		xml_matchers.append(MaintainerEmailMatcher(maintainer_emails))
	if opts.herd is not None:
		herds  = []
		for x in opts.herd:
			herds.extend(x.split(","))
		xml_matchers.append(HerdMatcher(herds))

	repos = []
	if opts.all_repos:
		repos.extend(portdb.repositories.get_repo_for_location(location)
			for location in portdb.porttrees)
	elif opts.repo is not None:
		repos.append(portdb.repositories[opts.repo])
	else:
		repos.append(portdb.repositories.mainRepo())

	if not atoms:
		names = None
		categories = list(portdb.categories)
	else:
		category_wildcard = False
		name_wildcard = False
		categories = []
		names = []
		for atom in atoms:
			category, name = portage.catsplit(atom.cp)
			categories.append(category)
			names.append(name)
			if "*" in category:
				category_wildcard = True
			if "*" in name:
				name_wildcard = True

		if category_wildcard:
			categories = list(portdb.categories)
		else:
			categories = list(set(categories))

		if name_wildcard:
			names = None
		else:
			names = sorted(set(names))

	no_version = opts.no_version
	categories.sort()

	for category in categories:
		if names is None:
			cp_list = portdb.cp_all(categories=(category,))
		else:
			cp_list = [category + "/" + name for name in names]
		for cp in cp_list:
			matches = []
			for repo in repos:
				match = True
				if xml_matchers:
					metadata_xml_path = os.path.join(
						repo.location, cp, 'metadata.xml')
					try:
						metadata_xml = MetaDataXML(metadata_xml_path, None)
					except (EnvironmentError, SyntaxError):
						match = False
					else:
						for matcher in xml_matchers:
							if not matcher(metadata_xml):
								match = False
								break
				if not match:
					continue
				cpv_list = portdb.cp_list(cp, mytree=[repo.location])
				if atoms:
					for cpv in cpv_list:
						pkg = None
						for atom in atoms:
							if atom.repo is not None and \
								atom.repo != repo.name:
								continue
							if not portage.match_from_list(atom, [cpv]):
								continue
							if need_metadata:
								if pkg is None:
									try:
										pkg = _pkg(cpv, repo.name)
									except portage.exception.PackageNotFound:
										continue

								if not (opts.no_filters or pkg.visible):
									continue
								if not portage.match_from_list(atom, [pkg]):
									continue
							matches.append(cpv)
							break
						if no_version and matches:
							break
				elif opts.no_filters:
					matches.extend(cpv_list)
				else:
					for cpv in cpv_list:
						try:
							pkg = _pkg(cpv, repo.name)
						except portage.exception.PackageNotFound:
							continue
						else:
							if pkg.visible:
								matches.append(cpv)
								if no_version:
									break

				if no_version and matches:
					break

			if not matches:
				continue

			if no_version:
				writemsg_stdout("%s\n" % (cp,), noiselevel=-1)
			else:
				matches = list(set(matches))
				portdb._cpv_sort_ascending(matches)
				for cpv in matches:
					writemsg_stdout("%s\n" % (cpv,), noiselevel=-1)

	return os.EX_OK


def use_reduce(argv):
	"""<depend_string>
	Reduce a dependency string possibly containing use conditionals.
	"""

	if len(argv) != 1:
		print("ERROR: wrong number of arguments")
		return 2
	from portage.dep import use_reduce as use_internal
	print(' '.join(use_internal(argv[0], uselist=os.environ['USE'].split(' '))))

#-----------------------------------------------------------------------------
#
# DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
#

non_commands = frozenset(['elog', 'eval_atom_use', 'exithandler', 'main', 'usage', 'uses_eroot'])
commands = sorted(k for k, v in globals().items() \
	if k not in non_commands and isinstance(v, types.FunctionType) and v.__module__ == "__main__")


def add_pquery_arguments(parser):
	pquery_option_groups = (
		(
			'Repository matching options',
			(
				{
					"longopt": "--no-filters",
					"action": "store_true",
					"help": "no visibility filters (ACCEPT_KEYWORDS, package masking, etc)"
				},
				{
					"longopt": "--repo",
					"help": "repo to use (default is PORTDIR if omitted)"
				},
				{
					"longopt": "--all-repos",
					"help": "search all repos"
				}
			)
		),
		(
			'Package matching options',
			(
				{
					"longopt": "--herd",
					"action": "append",
					"help": "exact match on a herd"
				},
				{
					"longopt": "--maintainer-email",
					"action": "append",
					"help": "comma-separated list of maintainer email regexes to search for"
				}
			)
		),
		(
			'Output formatting',
			(
				{
					"shortopt": "-n",
					"longopt": "--no-version",
					"action": "store_true",
					"help": "collapse multiple matching versions together"
				},
			)
		),
	)

	for group_title, opt_data in pquery_option_groups:
		arg_group = parser.add_argument_group(group_title)
		for opt_info in opt_data:
			pargs = []
			try:
				pargs.append(opt_info["shortopt"])
			except KeyError:
				pass
			try:
				pargs.append(opt_info["longopt"])
			except KeyError:
				pass

			kwargs = {}
			try:
				kwargs["action"] = opt_info["action"]
			except KeyError:
				pass
			try:
				kwargs["help"] = opt_info["help"]
			except KeyError:
				pass
			arg_group.add_argument(*pargs, **portage._native_kwargs(kwargs))


def usage(argv):
	print(">>> Portage information query tool")
	print(">>> %s" % portage.VERSION)
	print(">>> Usage: portageq <command> [<option> ...]")
	print("")
	print("Available commands:")

	#
	# Show our commands -- we do this by scanning the functions in this
	# file, and formatting each functions documentation.
	#
	help_mode = '--help' in argv
	for name in commands:
		# Drop non-functions
		obj = globals()[name]

		doc = obj.__doc__
		if (doc == None):
			print("   " + name)
			print("      MISSING DOCUMENTATION!")
			print("")
			continue

		lines = doc.lstrip("\n").split("\n")
		print("   " + name + " " + lines[0].strip())
		if len(argv) > 1:
			if (not help_mode):
				lines = lines[:-1]
			for line in lines[1:]:
				print("      " + line.strip())

	print()
	print('Pkgcore pquery compatible options:')
	print()
	parser = ArgumentParser(add_help=False,
		usage='portageq pquery [options] [atom ...]')
	add_pquery_arguments(parser)
	parser.print_help()

	if len(argv) == 1:
		print("\nRun portageq with --help for info")

atom_validate_strict = "EBUILD_PHASE" in os.environ
eapi = None
if atom_validate_strict:
	eapi = os.environ.get('EAPI')

	def elog(elog_funcname, lines):
		cmd = "source '%s/isolated-functions.sh' ; " % \
			os.environ["PORTAGE_BIN_PATH"]
		for line in lines:
			cmd += "%s %s ; " % (elog_funcname, portage._shell_quote(line))
		subprocess.call([portage.const.BASH_BINARY, "-c", cmd])

else:
	def elog(elog_funcname, lines):
		pass

def main(argv):

	argv = portage._decode_argv(argv)

	nocolor = os.environ.get('NOCOLOR')
	if nocolor in ('yes', 'true'):
		portage.output.nocolor()

	parser = ArgumentParser(add_help=False)

	# used by envvar
	parser.add_argument("-v", dest="verbose", action="store_true")

	actions = parser.add_argument_group('Actions')
	actions.add_argument("-h", "--help", action="store_true")
	actions.add_argument("--version", action="store_true")

	add_pquery_arguments(parser)

	opts, args = parser.parse_known_args(argv[1:])

	if opts.help:
		usage(argv)
		return os.EX_OK
	elif opts.version:
		print("Portage", portage.VERSION)
		return os.EX_OK

	cmd = None
	if args and args[0] in commands:
		cmd = args[0]

	if cmd == 'pquery':
		cmd = None
		args = args[1:]

	if cmd is None:
		return pquery(parser, opts, args)

	if opts.verbose:
		# used by envvar
		args.append("-v")

	argv = argv[:1] + args

	if len(argv) < 2:
		usage(argv)
		sys.exit(os.EX_USAGE)

	function = globals()[cmd]
	uses_eroot = getattr(function, "uses_eroot", False) and len(argv) > 2
	if uses_eroot:
		if not os.path.isdir(argv[2]):
			sys.stderr.write("Not a directory: '%s'\n" % argv[2])
			sys.stderr.write("Run portageq with --help for info\n")
			sys.stderr.flush()
			sys.exit(os.EX_USAGE)
		eprefix = portage.settings["EPREFIX"]
		eroot = portage.util.normalize_path(argv[2])

		if eprefix:
			if not eroot.endswith(eprefix):
				sys.stderr.write("ERROR: This version of portageq"
						 " only supports <eroot>s ending in"
						 " '%s'. The provided <eroot>, '%s',"
						 " doesn't.\n" % (eprefix, eroot))
				sys.stderr.flush()
				sys.exit(os.EX_USAGE)
			root = eroot[:1 - len(eprefix)]
		else:
			root = eroot

		os.environ["ROOT"] = root

	args = argv[2:]

	try:
		if uses_eroot:
			args[0] = portage.settings['EROOT']
		retval = function(args)
		if retval:
			sys.exit(retval)
	except portage.exception.PermissionDenied as e:
		sys.stderr.write("Permission denied: '%s'\n" % str(e))
		sys.exit(e.errno)
	except portage.exception.ParseError as e:
		sys.stderr.write("%s\n" % str(e))
		sys.exit(1)
	except portage.exception.AmbiguousPackageName as e:
		# Multiple matches thrown from cpv_expand
		pkgs = e.args[0]
		# An error has occurred so we writemsg to stderr and exit nonzero.
		portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
		for pkg in pkgs:
			portage.writemsg("* %s\n" % pkg, noiselevel=-1)
		portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
		sys.exit(1)

if __name__ == '__main__':
	sys.exit(main(sys.argv))

#-----------------------------------------------------------------------------
