#!/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

if os.path.isfile(os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), ".portage_not_installed")):
	pym_paths = [os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "pym")]
	sys.path.insert(0, pym_paths[0])
else:
	import distutils.sysconfig
	pym_paths = [os.path.join(distutils.sysconfig.get_python_lib(), x) for x in ("_emerge", "portage")]
# Avoid sandbox violations after Python upgrade.
if os.environ.get("SANDBOX_ON") == "1":
	sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
	for pym_path in pym_paths:
		if pym_path not in sandbox_write:
			sandbox_write.append(pym_path)
			os.environ["SANDBOX_WRITE"] = ":".join(filter(None, sandbox_write))
	del pym_path, sandbox_write
del pym_paths

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

# global to hold all function docstrings to be used for argparse help.
# Avoids python compilation level 2 optimization troubles.
docstrings = {}

#-----------------------------------------------------------------------------
#
# To add functionality to this tool, add a function below.
#
# The format for functions is:
#
#   def function(argv):
#       <code>
#
#   docstrings['function'] = """<list of options for this function>
#       <description of the function>
#       """
#   function.__doc__ = docstrings['function']
#
# "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):
	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

docstrings['has_version'] = """<eroot> <category/package>
	Return code 0 if it's available, 1 otherwise.
	"""
has_version.__doc__ = docstrings['has_version']


@uses_eroot
def best_version(argv):
	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

docstrings['best_version'] = """<eroot> <category/package>
	Returns category/package-version (without .ebuild).
	"""
best_version.__doc__ = docstrings['best_version']


@uses_eroot
def mass_best_version(argv):
	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

docstrings['mass_best_version'] = """<eroot> [<category/package>]+
	Returns category/package-version (without .ebuild).
	"""
mass_best_version.__doc__ = docstrings['mass_best_version']


@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

docstrings['metadata'] = """
<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_')))
metadata.__doc__ = docstrings['metadata']


@uses_eroot
def contents(argv):
	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)

docstrings['contents'] = """<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>.
	"""
contents.__doc__ = docstrings['contents']


@uses_eroot
def owners(argv):
	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

docstrings['owners'] = """<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.
	"""
owners.__doc__ = docstrings['owners']


@uses_eroot
def is_protected(argv):
	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

docstrings['is_protected'] = """<eroot> <filename>
	Given a single filename, return code 0 if it's protected, 1 otherwise.
	The filename must begin with <eroot>.
	"""
is_protected.__doc__ = docstrings['is_protected']


@uses_eroot
def filter_protected(argv):
	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

docstrings['filter_protected'] = """<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>.
	"""
filter_protected.__doc__ = docstrings['filter_protected']


@uses_eroot
def best_visible(argv):
	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

docstrings['best_visible'] = """<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.
	"""
best_visible.__doc__ = docstrings['best_visible']


@uses_eroot
def mass_best_visible(argv):
	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

docstrings['mass_best_visible'] = """<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.
	"""
mass_best_visible.__doc__ = docstrings['mass_best_visible']


@uses_eroot
def all_best_visible(argv):
	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)

docstrings['all_best_visible'] = """<eroot>
	Returns all best_visible packages (without .ebuild).
	"""
all_best_visible.__doc__ = docstrings['all_best_visible']


@uses_eroot
def match(argv):
	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)

docstrings['match'] = """<eroot> <atom>
	Returns a \\n separated list of category/package-version.
	When given an empty string, all installed packages will
	be listed.
	"""
match.__doc__ = docstrings['match']


@uses_eroot
def expand_virtual(argv):
	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

docstrings['expand_virtual'] = """<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.
	"""
expand_virtual.__doc__ = docstrings['expand_virtual']


def vdb_path(_argv):
	out = sys.stdout
	out.write(os.path.join(portage.settings["EROOT"], portage.VDB_PATH) + "\n")
	out.flush()
	return os.EX_OK

docstrings['vdb_path'] = """
	Returns the path used for the var(installed) package database for the
	set environment/configuration options.
	"""
vdb_path.__doc__ = docstrings['vdb_path']


def gentoo_mirrors(_argv):
	print(portage.settings["GENTOO_MIRRORS"])

docstrings['gentoo_mirrors'] = """
	Returns the mirrors set to use in the portage configuration.
	"""
gentoo_mirrors.__doc__ = docstrings['gentoo_mirrors']


@uses_eroot
def repositories_configuration(argv):
	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()

docstrings['repositories_configuration'] = """<eroot>
	Returns the configuration of repositories.
	"""
repositories_configuration.__doc__ = docstrings['repositories_configuration']


@uses_eroot
def repos_config(argv):
	return repositories_configuration(argv)

docstrings['repos_config'] = """
	<eroot>
	This is an alias for the repositories_configuration command.
	"""
repos_config.__doc__ = docstrings['repos_config']


def portdir(_argv):
	print("WARNING: 'portageq portdir' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
	print(portage.settings["PORTDIR"])

docstrings['portdir'] = """
	Returns the PORTDIR path.
	Deprecated in favor of repositories_configuration command.
	"""
portdir.__doc__ = docstrings['portdir']


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

docstrings['config_protect'] = """
	Returns the CONFIG_PROTECT paths.
	"""
config_protect.__doc__ = docstrings['config_protect']


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

docstrings['config_protect_mask'] = """
	Returns the CONFIG_PROTECT_MASK paths.
	"""
config_protect_mask.__doc__ = docstrings['config_protect_mask']

def portdir_overlay(_argv):
	print("WARNING: 'portageq portdir_overlay' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
	print(portage.settings["PORTDIR_OVERLAY"])

docstrings['portdir_overlay'] = """
	Returns the PORTDIR_OVERLAY path.
	Deprecated in favor of repositories_configuration command.
	"""
portdir_overlay.__doc__ = docstrings['portdir_overlay']


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

docstrings['pkgdir'] = """
	Returns the PKGDIR path.
	"""
pkgdir.__doc__ = docstrings['pkgdir']


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

docstrings['distdir'] = """
	Returns the DISTDIR path.
	"""
distdir.__doc__ = docstrings['distdir']


def colormap(_argv):
	print(portage.output.colormap())

docstrings['colormap'] = """
	Display the color.map as environment variables.
	"""
colormap.__doc__ = docstrings['colormap']


def envvar(argv):
	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])

docstrings['envvar'] = """<variable>+
	Returns a specific environment variable as exists prior to ebuild.sh.
	Similar to: emerge --verbose --info | egrep '^<variable>='
	"""
envvar.__doc__ = docstrings['envvar']


@uses_eroot
def get_repos(argv):
	if len(argv) < 1:
		print("ERROR: insufficient parameters!")
		return 2
	print(" ".join(reversed(portage.db[argv[0]]["vartree"].settings.repositories.prepos_order)))

docstrings['get_repos'] = """<eroot>
	Returns all repos with names (repo_name file) argv[0] = $EROOT
	"""
get_repos.__doc__ = docstrings['get_repos']


@uses_eroot
def master_repositories(argv):
	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))

docstrings['master_repositories'] = """<eroot> <repo_id>+
	Returns space-separated list of master repositories for specified repository.
	"""
master_repositories.__doc__ = docstrings['master_repositories']


@uses_eroot
def master_repos(argv):
	return master_repositories(argv)

docstrings['master_repos'] = """<eroot> <repo_id>+
	This is an alias for the master_repositories command.
	"""
master_repos.__doc__ = docstrings['master_repos']


@uses_eroot
def get_repo_path(argv):

	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)

docstrings['get_repo_path'] = """<eroot> <repo_id>+
	Returns the path to the repo named argv[1], argv[0] = $EROOT
	"""
get_repo_path.__doc__ = docstrings['get_repo_path']


@uses_eroot
def available_eclasses(argv):
	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)))

docstrings['available_eclasses'] = """<eroot> <repo_id>+
	Returns space-separated list of available eclasses for specified repository.
	"""
available_eclasses.__doc__ = docstrings['available_eclasses']


@uses_eroot
def eclass_path(argv):
	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

docstrings['eclass_path'] = """<eroot> <repo_id> <eclass>+
	Returns the path to specified eclass for specified repository.
	"""
eclass_path.__doc__ = docstrings['eclass_path']


@uses_eroot
def license_path(argv):
	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

docstrings['license_path'] = """<eroot> <repo_id> <license>+
	Returns the path to specified license for specified repository.
	"""
license_path.__doc__ = docstrings['license_path']


@uses_eroot
def list_preserved_libs(argv):
	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

docstrings['list_preserved_libs'] = """<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.
	"""
list_preserved_libs.__doc__ = docstrings['list_preserved_libs']


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):
	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

docstrings['pquery'] = """[options] [atom]+
	Emulates a subset of Pkgcore's pquery tool.
	"""
pquery.__doc__ = docstrings['pquery']


#-----------------------------------------------------------------------------
#
# 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:
		doc = docstrings.get(name)
		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))

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