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

"""Resolver output display operation.
"""

from __future__ import unicode_literals

__all__ = (
	"Display",
	)

import sys

import portage
from portage import os
from portage.dbapi.dep_expand import dep_expand
from portage.dep import cpvequal, _repo_separator, _slot_separator
from portage.eapi import _get_eapi_attrs
from portage.exception import InvalidDependString, SignatureException
from portage.package.ebuild.config import _get_feature_flags
from portage.package.ebuild._spawn_nofetch import spawn_nofetch
from portage.output import ( blue, colorize, create_color_func,
	darkblue, darkgreen, green, nc_len, teal)
bad = create_color_func("BAD")
from portage.util import writemsg_stdout
from portage.versions import best

from _emerge.Blocker import Blocker
from _emerge.create_world_atom import create_world_atom
from _emerge.resolver.output_helpers import ( _DisplayConfig, _tree_display,
	_PackageCounters, _create_use_string, _format_size, _calc_changelog, PkgInfo)
from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice

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


class Display(object):
	"""Formats and outputs the depgrah supplied it for merge/re-merge, etc.

	__call__()
	@param depgraph: list
	@param favorites: defaults to []
	@param verbosity: integer, defaults to None
	"""

	def __init__(self):
		self.changelogs = []
		self.print_msg = []
		self.blockers = []
		self.counters = _PackageCounters()
		self.resolver = None
		self.resolved = None
		self.vardb = None
		self.portdb = None
		self.verboseadd = ''
		self.oldlp = None
		self.myfetchlist = None
		self.indent = ''
		self.is_new = True
		self.cur_use = None
		self.cur_iuse = None
		self.old_use = ''
		self.old_iuse = ''
		self.use_expand = None
		self.use_expand_hidden = None
		self.pkgsettings = None
		self.forced_flags = None
		self.newlp = None
		self.conf = None
		self.blocker_style = None


	def _blockers(self, pkg):
		"""Processes pkg for blockers and adds colorized strings to
		self.print_msg and self.blockers

		@param pkg: _emerge.Package.Package instance
		@rtype: bool
		Modifies class globals: self.blocker_style, self.resolved,
			self.print_msg
		"""
		if pkg.satisfied:
			self.blocker_style = "PKG_BLOCKER_SATISFIED"
			addl = "%s     " % (colorize(self.blocker_style, "b"),)
		else:
			self.blocker_style = "PKG_BLOCKER"
			addl = "%s     " % (colorize(self.blocker_style, "B"),)
		addl += self.empty_space_in_brackets()
		self.resolved = dep_expand(
			str(pkg.atom).lstrip("!"), mydb=self.vardb,
			settings=self.pkgsettings
			)
		if self.conf.columns and self.conf.quiet:
			addl += " " + colorize(self.blocker_style, str(self.resolved))
		else:
			addl = "[%s %s] %s%s" % \
				(colorize(self.blocker_style, "blocks"),
				addl, self.indent,
				colorize(self.blocker_style, str(self.resolved))
				)
		block_parents = self.conf.blocker_parents.parent_nodes(pkg)
		block_parents = set([pnode[2] for pnode in block_parents])
		block_parents = ", ".join(block_parents)
		if self.resolved != pkg[2]:
			addl += colorize(self.blocker_style,
				" (\"%s\" is blocking %s)") % \
				(str(pkg.atom).lstrip("!"), block_parents)
		else:
			addl += colorize(self.blocker_style,
				" (is blocking %s)") % block_parents
		if isinstance(pkg, Blocker) and pkg.satisfied:
			if not self.conf.columns:
				self.print_msg.append(addl)
		else:
			self.blockers.append(addl)

	def _display_use(self, pkg, myoldbest, myinslotlist):
		""" USE flag display

		@param pkg: _emerge.Package.Package instance
		@param myoldbest: list of installed versions
		@param myinslotlist: list of installed slots
		Modifies class globals: self.forced_flags, self.cur_iuse,
			self.old_iuse, self.old_use, self.use_expand
		"""

		self.forced_flags = set()
		self.forced_flags.update(pkg.use.force)
		self.forced_flags.update(pkg.use.mask)

		self.cur_use = [flag for flag in self.conf.pkg_use_enabled(pkg) \
			if flag in pkg.iuse.all]
		self.cur_iuse = sorted(pkg.iuse.all)

		if myoldbest and myinslotlist:
			previous_cpv = myoldbest[0].cpv
		else:
			previous_cpv = pkg.cpv
		if self.vardb.cpv_exists(previous_cpv):
			previous_pkg = self.vardb.match_pkgs('=' + previous_cpv)[0]
			self.old_iuse = sorted(previous_pkg.iuse.all)
			self.old_use = previous_pkg.use.enabled
			self.is_new = False
		else:
			self.old_iuse = []
			self.old_use = []
			self.is_new = True

		self.old_use = [flag for flag in self.old_use if flag in self.old_iuse]

		self.use_expand = pkg.use.expand
		self.use_expand_hidden = pkg.use.expand_hidden
		return

	def include_mask_str(self):
		return self.conf.verbosity > 1

	def gen_mask_str(self, pkg):
		"""
		@param pkg: _emerge.Package.Package instance
		"""
		hardmasked = pkg.isHardMasked()
		mask_str = " "

		if hardmasked:
			mask_str = colorize("BAD", "#")
		else:
			keyword_mask = pkg.get_keyword_mask()

			if keyword_mask is None:
				pass
			elif keyword_mask == "missing":
				mask_str = colorize("BAD", "*")
			else:
				mask_str = colorize("WARN", "~")

		return mask_str

	def empty_space_in_brackets(self):
		space = ""
		if self.include_mask_str():
			# add column for mask status
			space += " "
		return space

	def map_to_use_expand(self, myvals, forced_flags=False,
		remove_hidden=True):
		"""Map use expand variables

		@param myvals: list
		@param forced_flags: bool
		@param remove_hidden: bool
		@rtype ret dictionary
			or ret dict, forced dict.
		"""
		ret = {}
		forced = {}
		for exp in self.use_expand:
			ret[exp] = []
			forced[exp] = set()
			for val in myvals[:]:
				if val.startswith(exp.lower()+"_"):
					if val in self.forced_flags:
						forced[exp].add(val[len(exp)+1:])
					ret[exp].append(val[len(exp)+1:])
					myvals.remove(val)
		ret["USE"] = myvals
		forced["USE"] = [val for val in myvals \
			if val in self.forced_flags]
		if remove_hidden:
			for exp in self.use_expand_hidden:
				ret.pop(exp, None)
		if forced_flags:
			return ret, forced
		return ret


	def recheck_hidden(self, pkg):
		""" Prevent USE_EXPAND_HIDDEN flags from being hidden if they
		are the only thing that triggered reinstallation.

		@param pkg: _emerge.Package.Package instance
		Modifies self.use_expand_hidden, self.use_expand, self.verboseadd
		"""
		reinst_flags_map = {}
		reinstall_for_flags = self.conf.reinstall_nodes.get(pkg)
		reinst_expand_map = None
		if reinstall_for_flags:
			reinst_flags_map = self.map_to_use_expand(
				list(reinstall_for_flags), remove_hidden=False)
			for k in list(reinst_flags_map):
				if not reinst_flags_map[k]:
					del reinst_flags_map[k]
			if not reinst_flags_map.get("USE"):
				reinst_expand_map = reinst_flags_map.copy()
				reinst_expand_map.pop("USE", None)
		if reinst_expand_map and \
			not set(reinst_expand_map).difference(
			self.use_expand_hidden):
			self.use_expand_hidden = \
				set(self.use_expand_hidden).difference(
				reinst_expand_map)

		cur_iuse_map, iuse_forced = \
			self.map_to_use_expand(self.cur_iuse, forced_flags=True)
		cur_use_map = self.map_to_use_expand(self.cur_use)
		old_iuse_map = self.map_to_use_expand(self.old_iuse)
		old_use_map = self.map_to_use_expand(self.old_use)

		use_expand = sorted(self.use_expand)
		use_expand.insert(0, "USE")
		feature_flags = _get_feature_flags(_get_eapi_attrs(pkg.eapi))

		for key in use_expand:
			if key in self.use_expand_hidden:
				continue
			self.verboseadd += _create_use_string(self.conf, key.upper(),
				cur_iuse_map[key], iuse_forced[key],
				cur_use_map[key], old_iuse_map[key],
				old_use_map[key], self.is_new, feature_flags,
				reinst_flags_map.get(key))
		return


	@staticmethod
	def pkgprint(pkg_str, pkg_info):
		"""Colorizes a string acording to pkg_info settings

		@param pkg_str: string
		@param pkg_info: dictionary
		@rtype colorized string
		"""
		if pkg_info.merge:
			if pkg_info.built:
				if pkg_info.system:
					return colorize("PKG_BINARY_MERGE_SYSTEM", pkg_str)
				elif pkg_info.world:
					return colorize("PKG_BINARY_MERGE_WORLD", pkg_str)
				else:
					return colorize("PKG_BINARY_MERGE", pkg_str)
			else:
				if pkg_info.system:
					return colorize("PKG_MERGE_SYSTEM", pkg_str)
				elif pkg_info.world:
					return colorize("PKG_MERGE_WORLD", pkg_str)
				else:
					return colorize("PKG_MERGE", pkg_str)
		elif pkg_info.operation == "uninstall":
			return colorize("PKG_UNINSTALL", pkg_str)
		else:
			if pkg_info.system:
				return colorize("PKG_NOMERGE_SYSTEM", pkg_str)
			elif pkg_info.world:
				return colorize("PKG_NOMERGE_WORLD", pkg_str)
			else:
				return colorize("PKG_NOMERGE", pkg_str)


	def verbose_size(self, pkg, repoadd_set, pkg_info):
		"""Determines the size of the downloads required

		@param pkg: _emerge.Package.Package instance
		@param repoadd_set: set of repos to add
		@param pkg_info: dictionary
		Modifies class globals: self.myfetchlist, self.counters.totalsize,
			self.verboseadd, repoadd_set.
		"""
		mysize = 0
		if pkg.type_name in ("binary", "ebuild") and pkg_info.merge:
			db = pkg.root_config.trees[
				pkg.root_config.pkg_tree_map[pkg.type_name]].dbapi
			kwargs = {}
			if pkg.type_name == "ebuild":
				kwargs["useflags"] = pkg_info.use
				kwargs["myrepo"] = pkg.repo
			myfilesdict = None
			try:
				myfilesdict = db.getfetchsizes(pkg.cpv,
					**portage._native_kwargs(kwargs))
			except InvalidDependString as e:
				# FIXME: validate SRC_URI earlier
				depstr, = db.aux_get(pkg.cpv,
					["SRC_URI"], myrepo=pkg.repo)
				show_invalid_depstring_notice(
					pkg, depstr, str(e))
				raise
			except SignatureException:
				# missing/invalid binary package SIZE signature
				pass
			if myfilesdict is None:
				myfilesdict = "[empty/missing/bad digest]"
			else:
				for myfetchfile in myfilesdict:
					if myfetchfile not in self.myfetchlist:
						mysize += myfilesdict[myfetchfile]
						self.myfetchlist.add(myfetchfile)
				if pkg_info.ordered:
					self.counters.totalsize += mysize
			self.verboseadd += _format_size(mysize)

		if self.quiet_repo_display:
			# overlay verbose
			# assign index for a previous version in the same slot
			slot_matches = self.vardb.match_pkgs(pkg.slot_atom)
			if slot_matches:
				repo_name_prev = slot_matches[0].repo
			else:
				repo_name_prev = None

			# now use the data to generate output
			if pkg.installed or not slot_matches:
				self.repoadd = self.conf.repo_display.repoStr(
					pkg_info.repo_path_real)
			else:
				repo_path_prev = None
				if repo_name_prev:
					repo_path_prev = self.portdb.getRepositoryPath(
						repo_name_prev)
				if repo_path_prev == pkg_info.repo_path_real:
					self.repoadd = self.conf.repo_display.repoStr(
						pkg_info.repo_path_real)
				else:
					self.repoadd = "%s=>%s" % (
						self.conf.repo_display.repoStr(repo_path_prev),
						self.conf.repo_display.repoStr(pkg_info.repo_path_real))
			if self.repoadd:
				repoadd_set.add(self.repoadd)


	def convert_myoldbest(self, pkg, pkg_info):
		"""converts and colorizes a version list to a string

		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionary
		@rtype string.
		"""
		myoldbest = pkg_info.oldbest_list
		# Convert myoldbest from a list to a string.
		myoldbest_str = ""
		if myoldbest:
			versions = []
			for pos, old_pkg in enumerate(myoldbest):
				key = old_pkg.version
				if key[-3:] == "-r0":
					key = key[:-3]
				if self.conf.verbosity == 3:
					if pkg_info.attr_display.new_slot:
						key += _slot_separator + old_pkg.slot
						if old_pkg.slot != old_pkg.sub_slot:
							key += "/" + old_pkg.sub_slot
					elif any(x.slot + "/" + x.sub_slot != "0/0" for x in myoldbest + [pkg]):
						key += _slot_separator + old_pkg.slot
						if old_pkg.slot != old_pkg.sub_slot or \
							old_pkg.slot == pkg.slot and old_pkg.sub_slot != pkg.sub_slot:
							key += "/" + old_pkg.sub_slot
					if not self.quiet_repo_display and (self.verbose_main_repo_display or
						any(x.repo != self.portdb.repositories.mainRepo().name for x in myoldbest + [pkg])):
						key += _repo_separator + old_pkg.repo
				versions.append(key)
			myoldbest_str = blue("["+", ".join(versions)+"]")
		return myoldbest_str

	def _append_slot(self, pkg_str, pkg, pkg_info):
		"""Potentially appends slot and subslot to package string.

		@param pkg_str: string
		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionary
		@rtype string
		"""
		if pkg_info.attr_display.new_slot:
			pkg_str += _slot_separator + pkg_info.slot
			if pkg_info.slot != pkg_info.sub_slot:
				pkg_str += "/" + pkg_info.sub_slot
		elif any(x.slot + "/" + x.sub_slot != "0/0" for x in pkg_info.oldbest_list + [pkg]):
			pkg_str += _slot_separator + pkg_info.slot
			if pkg_info.slot != pkg_info.sub_slot or \
				any(x.slot == pkg_info.slot and x.sub_slot != pkg_info.sub_slot for x in pkg_info.oldbest_list):
				pkg_str += "/" + pkg_info.sub_slot
		return pkg_str

	def _append_repository(self, pkg_str, pkg, pkg_info):
		"""Potentially appends repository to package string.

		@param pkg_str: string
		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionary
		@rtype string
		"""
		if not self.quiet_repo_display and (self.verbose_main_repo_display or
			any(x.repo != self.portdb.repositories.mainRepo().name for x in pkg_info.oldbest_list + [pkg])):
			pkg_str += _repo_separator + pkg.repo
		return pkg_str

	def _set_non_root_columns(self, pkg, pkg_info):
		"""sets the indent level and formats the output

		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionary
		@rtype string
		"""
		ver_str = pkg_info.ver
		if self.conf.verbosity == 3:
			ver_str = self._append_slot(ver_str, pkg, pkg_info)
			ver_str = self._append_repository(ver_str, pkg, pkg_info)
		if self.conf.quiet:
			myprint = str(pkg_info.attr_display) + " " + self.indent + \
				self.pkgprint(pkg_info.cp, pkg_info)
			myprint = myprint+darkblue(" "+ver_str)+" "
			myprint = myprint+pkg_info.oldbest
			myprint = myprint+darkgreen("to "+pkg.root)
			self.verboseadd = None
		else:
			if not pkg_info.merge:
				myprint = "[%s] %s%s" % \
					(self.pkgprint(pkg_info.operation.ljust(13), pkg_info),
					self.indent, self.pkgprint(pkg.cp, pkg_info))
			else:
				myprint = "[%s %s] %s%s" % \
					(self.pkgprint(pkg.type_name, pkg_info),
					pkg_info.attr_display,
					self.indent, self.pkgprint(pkg.cp, pkg_info))
			if (self.newlp-nc_len(myprint)) > 0:
				myprint = myprint+(" "*(self.newlp-nc_len(myprint)))
			myprint = myprint+" "+darkblue("["+ver_str+"]")+" "
			if (self.oldlp-nc_len(myprint)) > 0:
				myprint = myprint+" "*(self.oldlp-nc_len(myprint))
			myprint = myprint+pkg_info.oldbest
			myprint += darkgreen("to " + pkg.root)
		return myprint


	def _set_root_columns(self, pkg, pkg_info):
		"""sets the indent level and formats the output

		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionary
		@rtype string
		Modifies self.verboseadd
		"""
		ver_str = pkg_info.ver
		if self.conf.verbosity == 3:
			ver_str = self._append_slot(ver_str, pkg, pkg_info)
			ver_str = self._append_repository(ver_str, pkg, pkg_info)
		if self.conf.quiet:
			myprint = str(pkg_info.attr_display) + " " + self.indent + \
				self.pkgprint(pkg_info.cp, pkg_info)
			myprint = myprint+" "+green(ver_str)+" "
			myprint = myprint+pkg_info.oldbest
			self.verboseadd = None
		else:
			if not pkg_info.merge:
				addl = self.empty_space_in_brackets()
				myprint = "[%s%s] %s%s" % \
					(self.pkgprint(pkg_info.operation.ljust(13), pkg_info),
					addl, self.indent, self.pkgprint(pkg.cp, pkg_info))
			else:
				myprint = "[%s %s] %s%s" % \
					(self.pkgprint(pkg.type_name, pkg_info),
					pkg_info.attr_display,
					self.indent, self.pkgprint(pkg.cp, pkg_info))
			if (self.newlp-nc_len(myprint)) > 0:
				myprint = myprint+(" "*(self.newlp-nc_len(myprint)))
			myprint = myprint+" "+green("["+ver_str+"]")+" "
			if (self.oldlp-nc_len(myprint)) > 0:
				myprint = myprint+(" "*(self.oldlp-nc_len(myprint)))
			myprint += pkg_info.oldbest
		return myprint


	def _set_no_columns(self, pkg, pkg_info):
		"""prints pkg info without column indentation.

		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionary
		@rtype the updated addl
		"""
		pkg_str = pkg.cpv
		if self.conf.verbosity == 3:
			pkg_str = self._append_slot(pkg_str, pkg, pkg_info)
			pkg_str = self._append_repository(pkg_str, pkg, pkg_info)
		if not pkg_info.merge:
			addl = self.empty_space_in_brackets()
			myprint = "[%s%s] %s%s %s" % \
				(self.pkgprint(pkg_info.operation.ljust(13),
				pkg_info), addl,
				self.indent, self.pkgprint(pkg_str, pkg_info),
				pkg_info.oldbest)
		else:
			myprint = "[%s %s] %s%s %s" % \
				(self.pkgprint(pkg.type_name, pkg_info),
				pkg_info.attr_display, self.indent,
				self.pkgprint(pkg_str, pkg_info), pkg_info.oldbest)
		return myprint

	def print_messages(self, show_repos):
		"""Performs the actual output printing of the pre-formatted
		messages

		@param show_repos: bool.
		"""
		for msg in self.print_msg:
			if isinstance(msg, basestring):
				writemsg_stdout("%s\n" % (msg,), noiselevel=-1)
				continue
			myprint, self.verboseadd, repoadd = msg
			if self.verboseadd:
				myprint += " " + self.verboseadd
			if show_repos and repoadd:
				myprint += " " + teal("[%s]" % repoadd)
			writemsg_stdout("%s\n" % (myprint,), noiselevel=-1)
		return


	def print_blockers(self):
		"""Performs the actual output printing of the pre-formatted
		blocker messages
		"""
		for pkg in self.blockers:
			writemsg_stdout("%s\n" % (pkg,), noiselevel=-1)
		return


	def print_verbose(self, show_repos):
		"""Prints the verbose output to std_out

		@param show_repos: bool.
		"""
		writemsg_stdout('\n%s\n' % (self.counters,), noiselevel=-1)
		if show_repos:
			# Use unicode_literals to force unicode format string so
			# that RepoDisplay.__unicode__() is called in python2.
			writemsg_stdout("%s" % (self.conf.repo_display,),
				noiselevel=-1)
		return


	def print_changelog(self):
		"""Prints the changelog text to std_out
		"""
		for chunk in self.changelogs:
			writemsg_stdout(chunk,
				noiselevel=-1)


	def get_display_list(self, mylist):
		"""Determines the display list to process

		@param mylist
		@rtype list
		Modifies self.counters.blocks, self.counters.blocks_satisfied,

		"""
		unsatisfied_blockers = []
		ordered_nodes = []
		for pkg in mylist:
			if isinstance(pkg, Blocker):
				self.counters.blocks += 1
				if pkg.satisfied:
					ordered_nodes.append(pkg)
					self.counters.blocks_satisfied += 1
				else:
					unsatisfied_blockers.append(pkg)
			else:
				ordered_nodes.append(pkg)
		if self.conf.tree_display:
			display_list = _tree_display(self.conf, ordered_nodes)
		else:
			display_list = [(pkg, 0, True) for pkg in ordered_nodes]
		for pkg in unsatisfied_blockers:
			display_list.append((pkg, 0, True))
		return display_list


	def set_pkg_info(self, pkg, ordered):
		"""Sets various pkg_info dictionary variables

		@param pkg: _emerge.Package.Package instance
		@param ordered: bool
		@rtype pkg_info dictionary
		Modifies self.counters.restrict_fetch,
			self.counters.restrict_fetch_satisfied
		"""
		pkg_info = PkgInfo()
		pkg_info.cp = pkg.cp
		pkg_info.ver = self.get_ver_str(pkg)
		pkg_info.slot = pkg.slot
		pkg_info.sub_slot = pkg.sub_slot
		pkg_info.repo_name = pkg.repo
		pkg_info.ordered = ordered
		pkg_info.operation = pkg.operation
		pkg_info.merge = ordered and pkg_info.operation == "merge"
		if not pkg_info.merge and pkg_info.operation == "merge":
			pkg_info.operation = "nomerge"
		pkg_info.built = pkg.type_name != "ebuild"
		pkg_info.ebuild_path = None
		if ordered:
			if pkg_info.merge:
				if pkg.type_name == "binary":
					self.counters.binary += 1
			elif pkg_info.operation == "uninstall":
				self.counters.uninst += 1
		if pkg.type_name == "ebuild":
			pkg_info.ebuild_path = self.portdb.findname(
				pkg.cpv, myrepo=pkg_info.repo_name)
			if pkg_info.ebuild_path is None:
				raise AssertionError(
					"ebuild not found for '%s'" % pkg.cpv)
			pkg_info.repo_path_real = os.path.dirname(os.path.dirname(
				os.path.dirname(pkg_info.ebuild_path)))
		else:
			pkg_info.repo_path_real = self.portdb.getRepositoryPath(pkg.repo)
		pkg_info.use = list(self.conf.pkg_use_enabled(pkg))
		if not pkg.built and pkg.operation == 'merge' and \
			'fetch' in pkg.restrict:
			if pkg_info.ordered:
				self.counters.restrict_fetch += 1
			pkg_info.attr_display.fetch_restrict = True
			if not self.portdb.getfetchsizes(pkg.cpv,
				useflags=pkg_info.use, myrepo=pkg.repo):
				pkg_info.attr_display.fetch_restrict_satisfied = True
				if pkg_info.ordered:
					self.counters.restrict_fetch_satisfied += 1
			else:
				if pkg_info.ebuild_path is not None:
					self.restrict_fetch_list[pkg] = pkg_info
		return pkg_info


	def do_changelog(self, pkg, pkg_info):
		"""Processes and adds the changelog text to the master text for output

		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionay
		Modifies self.changelogs
		"""
		inst_matches = self.vardb.match(pkg.slot_atom)
		if inst_matches:
			ebuild_path_cl = pkg_info.ebuild_path
			if ebuild_path_cl is None:
				# binary package
				ebuild_path_cl = self.portdb.findname(pkg.cpv, myrepo=pkg.repo)
			if ebuild_path_cl is not None:
				self.changelogs.extend(_calc_changelog(
					ebuild_path_cl, inst_matches[0], pkg.cpv))
		return


	def check_system_world(self, pkg):
		"""Checks for any occurances of the package in the system or world sets

		@param pkg: _emerge.Package.Package instance
		@rtype system and world booleans
		"""
		root_config = self.conf.roots[pkg.root]
		system_set = root_config.sets["system"]
		world_set  = root_config.sets["selected"]
		system = False
		world = False
		try:
			system = system_set.findAtomForPackage(
				pkg, modified_use=self.conf.pkg_use_enabled(pkg))
			world = world_set.findAtomForPackage(
				pkg, modified_use=self.conf.pkg_use_enabled(pkg))
			if not (self.conf.oneshot or world) and \
				pkg.root == self.conf.target_root and \
				self.conf.favorites.findAtomForPackage(
					pkg, modified_use=self.conf.pkg_use_enabled(pkg)
					):
				# Maybe it will be added to world now.
				if create_world_atom(pkg, self.conf.favorites, root_config):
					world = True
		except InvalidDependString:
			# This is reported elsewhere if relevant.
			pass
		return system, world


	@staticmethod
	def get_ver_str(pkg):
		"""Obtains the version string
		@param pkg: _emerge.Package.Package instance
		@rtype string
		"""
		ver_str = pkg.cpv.version
		if ver_str.endswith("-r0"):
			ver_str = ver_str[:-3]
		return ver_str


	def _get_installed_best(self, pkg, pkg_info):
		""" we need to use "--emptrytree" testing here rather than
		"empty" param testing because "empty"
		param is used for -u, where you still *do* want to see when
		something is being upgraded.

		@param pkg: _emerge.Package.Package instance
		@param pkg_info: dictionay
		@rtype addl, myoldbest: list, myinslotlist: list
		Modifies self.counters.reinst, self.counters.new

		"""
		myoldbest = []
		myinslotlist = None
		installed_versions = self.vardb.match_pkgs(pkg.cp)
		if self.vardb.cpv_exists(pkg.cpv):
			pkg_info.attr_display.replace = True
			installed_version = self.vardb.match_pkgs(pkg.cpv)[0]
			if installed_version.slot != pkg.slot or installed_version.sub_slot != pkg.sub_slot or \
				not self.quiet_repo_display and installed_version.repo != pkg.repo:
				myoldbest = [installed_version]
			if pkg_info.ordered:
				if pkg_info.merge:
					self.counters.reinst += 1
		# filter out old-style virtual matches
		elif installed_versions and \
			installed_versions[0].cp == pkg.cp:
			myinslotlist = self.vardb.match_pkgs(pkg.slot_atom)
			# If this is the first install of a new-style virtual, we
			# need to filter out old-style virtual matches.
			if myinslotlist and \
				myinslotlist[0].cp != pkg.cp:
				myinslotlist = None
			if myinslotlist:
				myoldbest = myinslotlist[:]
				if not cpvequal(pkg.cpv,
					best([pkg.cpv] + [x.cpv for x in myinslotlist])):
					# Downgrade in slot
					pkg_info.attr_display.new_version = True
					pkg_info.attr_display.downgrade = True
					if pkg_info.ordered:
						self.counters.downgrades += 1
				else:
					# Update in slot
					pkg_info.attr_display.new_version = True
					if pkg_info.ordered:
						self.counters.upgrades += 1
			else:
				myoldbest = installed_versions
				pkg_info.attr_display.new = True
				pkg_info.attr_display.new_slot = True
				if pkg_info.ordered:
					self.counters.newslot += 1
			if self.conf.changelog:
				self.do_changelog(pkg, pkg_info)
		else:
			pkg_info.attr_display.new = True
			if pkg_info.ordered:
				self.counters.new += 1
		return myoldbest, myinslotlist


	def __call__(self, depgraph, mylist, favorites=None, verbosity=None):
		"""The main operation to format and display the resolver output.

		@param depgraph: dependency grah
		@param mylist: list of packages being processed
		@param favorites: list, defaults to []
		@param verbosity: verbose level, defaults to None
		Modifies self.conf, self.myfetchlist, self.portdb, self.vardb,
			self.pkgsettings, self.verboseadd, self.oldlp, self.newlp,
			self.print_msg,
		"""
		if favorites is None:
			favorites = []
		self.conf = _DisplayConfig(depgraph, mylist, favorites, verbosity)
		mylist = self.get_display_list(self.conf.mylist)
		# files to fetch list - avoids counting a same file twice
		# in size display (verbose mode)
		self.myfetchlist = set()

		self.quiet_repo_display = "--quiet-repo-display" in depgraph._frozen_config.myopts
		if self.quiet_repo_display:
			# Use this set to detect when all the "repoadd" strings are "[0]"
			# and disable the entire repo display in this case.
			repoadd_set = set()

		self.verbose_main_repo_display = "--verbose-main-repo-display" in depgraph._frozen_config.myopts
		self.restrict_fetch_list = {}

		for mylist_index in range(len(mylist)):
			pkg, depth, ordered = mylist[mylist_index]
			self.portdb = self.conf.trees[pkg.root]["porttree"].dbapi
			self.vardb = self.conf.trees[pkg.root]["vartree"].dbapi
			self.pkgsettings = self.conf.pkgsettings[pkg.root]
			self.indent = " " * depth

			if isinstance(pkg, Blocker):
				self._blockers(pkg)
			else:
				pkg_info = self.set_pkg_info(pkg, ordered)
				pkg_info.oldbest_list, myinslotlist = \
					self._get_installed_best(pkg, pkg_info)
				if ordered and pkg_info.merge and \
					not pkg_info.attr_display.new:
					for arg, atom in depgraph._iter_atoms_for_pkg(pkg):
						if arg.force_reinstall:
							pkg_info.attr_display.force_reinstall = True
							break

				self.verboseadd = ""
				if self.quiet_repo_display:
					self.repoadd = None
				self._display_use(pkg, pkg_info.oldbest_list, myinslotlist)
				self.recheck_hidden(pkg)
				if self.conf.verbosity == 3:
					if self.quiet_repo_display:
						self.verbose_size(pkg, repoadd_set, pkg_info)
					else:
						self.verbose_size(pkg, None, pkg_info)

				self.oldlp = self.conf.columnwidth - 30
				self.newlp = self.oldlp - 30
				pkg_info.oldbest = self.convert_myoldbest(pkg, pkg_info)
				pkg_info.system, pkg_info.world = \
					self.check_system_world(pkg)
				if 'interactive' in pkg.properties and \
					pkg.operation == 'merge':
					pkg_info.attr_display.interactive = True
					if ordered:
						self.counters.interactive += 1

				if self.include_mask_str():
					pkg_info.attr_display.mask = self.gen_mask_str(pkg)

				if pkg.root_config.settings["ROOT"] != "/":
					if pkg_info.oldbest:
						pkg_info.oldbest += " "
					if self.conf.columns:
						myprint = self._set_non_root_columns(pkg, pkg_info)
					else:
						pkg_str = pkg.cpv
						if self.conf.verbosity == 3:
							pkg_str = self._append_slot(pkg_str, pkg, pkg_info)
							pkg_str = self._append_repository(pkg_str, pkg, pkg_info)
						if not pkg_info.merge:
							addl = self.empty_space_in_brackets()
							myprint = "[%s%s] " % (
								self.pkgprint(pkg_info.operation.ljust(13),
								pkg_info), addl,
								)
						else:
							myprint = "[%s %s] " % (
								self.pkgprint(pkg.type_name, pkg_info),
								pkg_info.attr_display)
						myprint += self.indent + \
							self.pkgprint(pkg_str, pkg_info) + " " + \
							pkg_info.oldbest + darkgreen("to " + pkg.root)
				else:
					if self.conf.columns:
						myprint = self._set_root_columns(pkg, pkg_info)
					else:
						myprint = self._set_no_columns(pkg, pkg_info)

				if self.conf.columns and pkg.operation == "uninstall":
					continue
				if self.quiet_repo_display:
					self.print_msg.append((myprint, self.verboseadd, self.repoadd))
				else:
					self.print_msg.append((myprint, self.verboseadd, None))

		show_repos = self.quiet_repo_display and repoadd_set and repoadd_set != set(["0"])

		# now finally print out the messages
		self.print_messages(show_repos)
		self.print_blockers()
		if self.conf.verbosity == 3:
			self.print_verbose(show_repos)
		for pkg, pkg_info in self.restrict_fetch_list.items():
			writemsg_stdout("\nFetch instructions for %s:\n" % (pkg.cpv,),
							noiselevel=-1)
			spawn_nofetch(self.conf.trees[pkg.root]["porttree"].dbapi,
				pkg_info.ebuild_path)
		if self.conf.changelog:
			self.print_changelog()

		return os.EX_OK
