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

"""Resolver output display operation.
"""

from __future__ import unicode_literals

__all__ = (
	"Display", "format_unmatched_atom",
	)

import sys

import portage
from portage import os
from portage.dbapi.dep_expand import dep_expand
from portage.dep import Atom, cpvequal, _repo_separator, _slot_separator
from portage.eapi import _get_eapi_attrs
from portage.exception import InvalidDependString, SignatureException
from portage.localization import localized_size
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._sets.base import InternalPackageSet
from portage.util import writemsg_stdout
from portage.versions import best, cpv_getversion

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, _calc_changelog, PkgInfo)
from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice

if sys.hexversion >= 0x3000000:
	basestring = str
	_unicode = str
else:
	_unicode = unicode

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.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, blocker):
		"""Adds colorized strings to
		self.print_msg and self.blockers

		@param blocker: _emerge.Blocker.Blocker instance
		@rtype: bool
		Modifies class globals: self.blocker_style, self.resolved,
			self.print_msg
		"""
		if blocker.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(
			_unicode(blocker.atom).lstrip("!"), mydb=self.vardb,
			settings=self.pkgsettings
			)
		if self.conf.columns and self.conf.quiet:
			addl += " " + colorize(self.blocker_style, _unicode(self.resolved))
		else:
			addl = "[%s %s] %s%s" % \
				(colorize(self.blocker_style, "blocks"),
				addl, self.indent,
				colorize(self.blocker_style, _unicode(self.resolved))
				)
		block_parents = self.conf.blocker_parents.parent_nodes(blocker)
		block_parents = set(_unicode(pnode.cpv) for pnode in block_parents)
		block_parents = ", ".join(block_parents)
		if blocker.atom.blocker.overlap.forbid:
			blocking_desc = "hard blocking"
		else:
			blocking_desc = "blocking"
		if self.resolved != blocker.atom:
			addl += colorize(self.blocker_style,
				" (\"%s\" is %s %s)" %
				(_unicode(blocker.atom).lstrip("!"),
				blocking_desc, block_parents))
		else:
			addl += colorize(self.blocker_style,
				" (is %s %s)" % (blocking_desc, block_parents))
		if blocker.satisfied:
			if not self.conf.columns:
				self.print_msg.append(addl)
		else:
			self.blockers.append(addl)

	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 _display_use(self, pkg, pkg_info):
		""" USE flag display

		@param pkg: _emerge.Package.Package instance
		@param pkg_info: PkgInfo instance
		Modifies self.use_expand_hidden, self.use_expand, self.verboseadd,
			self.forced_flags
		"""

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

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

		if pkg_info.previous_pkg is not None:
			previous_pkg = pkg_info.previous_pkg
			old_iuse = sorted(previous_pkg.iuse.all)
			old_use = previous_pkg.use.enabled
			is_new = False
		else:
			old_iuse = []
			old_use = []
			is_new = True

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

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

		# Prevent USE_EXPAND_HIDDEN flags from being hidden if they
		# are the only thing that triggered reinstallation.
		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(cur_iuse, forced_flags=True)
		cur_use_map = self.map_to_use_expand(cur_use)
		old_iuse_map = self.map_to_use_expand(old_iuse)
		old_use_map = self.map_to_use_expand(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], 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, _unicode(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 += localized_size(mysize)

		if self.quiet_repo_display:
			# overlay verbose
			# assign index for a previous version in the same slot
			if pkg_info.previous_pkg is not None:
				repo_name_prev = pkg_info.previous_pkg.repo
			else:
				repo_name_prev = None

			# now use the data to generate output
			if pkg.installed or pkg_info.previous_pkg is None:
				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:
						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:
			pkg_str += _repo_separator + pkg.repo
		return pkg_str

	def _append_build_id(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 pkg.type_name == "binary" and pkg.cpv.build_id is not None:
			pkg_str += "-%s" % pkg.cpv.build_id
		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 = self._append_build_id(pkg_info.ver, pkg, pkg_info)
		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 = _unicode(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 = self._append_build_id(pkg_info.ver, pkg, pkg_info)
		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 = _unicode(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 = self._append_build_id(pkg.cpv, pkg, pkg_info)
		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

		if self.vardb.cpv_exists(pkg.cpv):
			# Do a cpv match first, in case the SLOT has changed.
			pkg_info.previous_pkg = self.vardb.match_pkgs(
				Atom('=' + pkg.cpv))[0]
		else:
			slot_matches = self.vardb.match_pkgs(pkg.slot_atom)
			if slot_matches:
				pkg_info.previous_pkg = slot_matches[0]

		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
		"""
		if pkg_info.previous_pkg is not None:
			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, pkg_info.previous_pkg, 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(Atom(pkg.cp))
		if self.vardb.cpv_exists(pkg.cpv):
			pkg_info.attr_display.replace = True
			installed_version = pkg_info.previous_pkg
			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.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)
				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 = self._append_build_id(
							pkg.cpv, pkg, pkg_info)
						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


def format_unmatched_atom(pkg, atom, pkg_use_enabled):
	"""
	Returns two strings. The first string contains the
	'atom' with parts of the atom colored, which 'pkg'
	doesn't match. The second string has the same number
	of characters as the first one, but consists of only
	white space or ^. The ^ characters have the same position
	as the colored parts of the first string.
	"""
	# Things to check:
	#	1. Version
	#	2. cp
	#   3. slot/sub_slot
	#	4. repository
	#	5. USE

	if atom.soname:
		return "%s" % (atom,), ""

	highlight = set()

	def perform_coloring():
		atom_str = ""
		marker_str = ""
		for ii, x in enumerate(atom):
			if ii in highlight:
				atom_str += colorize("BAD", x)
				marker_str += "^"
			else:
				atom_str += x
				marker_str += " "
		return atom_str, marker_str

	if atom.cp != pkg.cp:
		# Highlight the cp part only.
		ii = atom.find(atom.cp)
		highlight.update(range(ii, ii + len(atom.cp)))
		return perform_coloring()

	version_atom = atom.without_repo.without_slot.without_use
	version_atom_set = InternalPackageSet(initial_atoms=(version_atom,))
	highlight_version = not bool(version_atom_set.findAtomForPackage(pkg,
		modified_use=pkg_use_enabled(pkg)))

	highlight_slot = False
	if (atom.slot and atom.slot != pkg.slot) or \
		(atom.sub_slot and atom.sub_slot != pkg.sub_slot):
		highlight_slot = True

	if highlight_version:
		op = atom.operator
		ver = None
		if atom.cp != atom.cpv:
			ver = cpv_getversion(atom.cpv)

		if op == "=*":
			op = "="
			ver += "*"

		if op is not None:
			highlight.update(range(len(op)))

		if ver is not None:
			start = atom.rfind(ver)
			end = start + len(ver)
			highlight.update(range(start, end))

	if highlight_slot:
		slot_str = ":" + atom.slot
		if atom.sub_slot:
			slot_str += "/" + atom.sub_slot
		if atom.slot_operator:
			slot_str += atom.slot_operator
		start = atom.find(slot_str)
		end = start + len(slot_str)
		highlight.update(range(start, end))

	highlight_use = set()
	if atom.use:
		use_atom = "%s[%s]" % (atom.cp, str(atom.use))
		use_atom_set = InternalPackageSet(initial_atoms=(use_atom,))
		if not use_atom_set.findAtomForPackage(pkg, \
			modified_use=pkg_use_enabled(pkg)):
			missing_iuse = pkg.iuse.get_missing_iuse(
				atom.unevaluated_atom.use.required)
			if missing_iuse:
				highlight_use = set(missing_iuse)
			else:
				#Use conditionals not met.
				violated_atom = atom.violated_conditionals(
					pkg_use_enabled(pkg), pkg.iuse.is_valid_flag)
				if violated_atom.use is not None:
					highlight_use = set(violated_atom.use.enabled.union(
						violated_atom.use.disabled))

	if highlight_use:
		ii = atom.find("[") + 1
		for token in atom.use.tokens:
			if token.lstrip("-!").rstrip("=?") in highlight_use:
				highlight.update(range(ii, ii + len(token)))
			ii += len(token) + 1

	return perform_coloring()
