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

__all__ = (
	"display", "filter_iuse_defaults",
	)

import codecs
import re
import sys

from portage import os
from portage import _encodings, _unicode_decode, _unicode_encode
from portage.dbapi.dep_expand import dep_expand
from portage.const import PORTAGE_PACKAGE_ATOM
from portage.dep import cpvequal, match_from_list
from portage.exception import InvalidDependString
from portage._sets.base import InternalPackageSet
from portage.output import blue, bold, colorize, create_color_func, darkblue, darkgreen, green, nc_len, red, \
	teal, turquoise, yellow
bad = create_color_func("BAD")
from portage.util import writemsg, writemsg_stdout
from portage.versions import best, catpkgsplit, cpv_getkey

from _emerge.Blocker import Blocker
from _emerge.create_world_atom import create_world_atom
from _emerge.Package import Package

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

def filter_iuse_defaults(iuse):
	for flag in iuse:
		if flag.startswith("+") or flag.startswith("-"):
			yield flag[1:]
		else:
			yield flag

class _RepoDisplay(object):
	def __init__(self, roots):
		self._shown_repos = {}
		self._unknown_repo = False
		repo_paths = set()
		for root_config in roots.values():
			portdir = root_config.settings.get("PORTDIR")
			if root_config.settings.repositories:
				repo_paths.update(root_config.settings.repositories.repoUserLocationList())
		repo_paths = list(repo_paths)
		self._repo_paths = repo_paths
		self._repo_paths_real = [ os.path.realpath(repo_path) \
			for repo_path in repo_paths ]

		# pre-allocate index for PORTDIR so that it always has index 0.
		for root_config in roots.values():
			portdb = root_config.trees["porttree"].dbapi
			portdir = portdb.porttree_root
			if portdir:
				self.repoStr(portdir)

	def repoStr(self, repo_path_real):
		real_index = -1
		if repo_path_real:
			real_index = self._repo_paths_real.index(repo_path_real)
		if real_index == -1:
			s = "?"
			self._unknown_repo = True
		else:
			shown_repos = self._shown_repos
			repo_paths = self._repo_paths
			repo_path = repo_paths[real_index]
			index = shown_repos.get(repo_path)
			if index is None:
				index = len(shown_repos)
				shown_repos[repo_path] = index
			s = str(index)
		return s

	def __str__(self):
		output = []
		shown_repos = self._shown_repos
		unknown_repo = self._unknown_repo
		if shown_repos or self._unknown_repo:
			output.append("Portage tree and overlays:\n")
		show_repo_paths = list(shown_repos)
		for repo_path, repo_index in shown_repos.items():
			show_repo_paths[repo_index] = repo_path
		if show_repo_paths:
			for index, repo_path in enumerate(show_repo_paths):
				output.append(" "+teal("["+str(index)+"]")+" %s\n" % repo_path)
		if unknown_repo:
			output.append(" "+teal("[?]") + \
				" indicates that the source repository could not be determined\n")
		return "".join(output)

	if sys.hexversion < 0x3000000:

		__unicode__ = __str__

		def __str__(self):
			return _unicode_encode(self.__unicode__(),
				encoding=_encodings['content'])

class _PackageCounters(object):

	def __init__(self):
		self.upgrades   = 0
		self.downgrades = 0
		self.new        = 0
		self.newslot    = 0
		self.reinst     = 0
		self.uninst     = 0
		self.blocks     = 0
		self.blocks_satisfied         = 0
		self.totalsize  = 0
		self.restrict_fetch           = 0
		self.restrict_fetch_satisfied = 0
		self.interactive              = 0
		self.binary                   = 0

	def __str__(self):
		total_installs = self.upgrades + self.downgrades + self.newslot + self.new + self.reinst
		myoutput = []
		details = []
		myoutput.append("Total: %s package" % total_installs)
		if total_installs != 1:
			myoutput.append("s")
		if total_installs != 0:
			myoutput.append(" (")
		if self.upgrades > 0:
			details.append("%s upgrade" % self.upgrades)
			if self.upgrades > 1:
				details[-1] += "s"
		if self.downgrades > 0:
			details.append("%s downgrade" % self.downgrades)
			if self.downgrades > 1:
				details[-1] += "s"
		if self.new > 0:
			details.append("%s new" % self.new)
		if self.newslot > 0:
			details.append("%s in new slot" % self.newslot)
			if self.newslot > 1:
				details[-1] += "s"
		if self.reinst > 0:
			details.append("%s reinstall" % self.reinst)
			if self.reinst > 1:
				details[-1] += "s"
		if self.binary > 0:
			details.append("%s binary" % self.binary)
			if self.binary > 1:
				details[-1] = details[-1][:-1] + "ies"
		if self.uninst > 0:
			details.append("%s uninstall" % self.uninst)
			if self.uninst > 1:
				details[-1] += "s"
		if self.interactive > 0:
			details.append("%s %s" % (self.interactive,
				colorize("WARN", "interactive")))
		myoutput.append(", ".join(details))
		if total_installs != 0:
			myoutput.append(")")
		myoutput.append(", Size of downloads: %s" % _format_size(self.totalsize))
		if self.restrict_fetch:
			myoutput.append("\nFetch Restriction: %s package" % \
				self.restrict_fetch)
			if self.restrict_fetch > 1:
				myoutput.append("s")
		if self.restrict_fetch_satisfied < self.restrict_fetch:
			myoutput.append(bad(" (%s unsatisfied)") % \
				(self.restrict_fetch - self.restrict_fetch_satisfied))
		if self.blocks > 0:
			myoutput.append("\nConflict: %s block" % \
				self.blocks)
			if self.blocks > 1:
				myoutput.append("s")
			if self.blocks_satisfied < self.blocks:
				myoutput.append(bad(" (%s unsatisfied)") % \
					(self.blocks - self.blocks_satisfied))
		return "".join(myoutput)

class _DisplayConfig(object):
	def __init__(self, depgraph, mylist, favorites, verbosity):
		frozen_config = depgraph._frozen_config
		dynamic_config = depgraph._dynamic_config

		self.mylist = mylist
		self.favorites = InternalPackageSet(favorites, allow_repo=True)
		self.verbosity = verbosity

		if self.verbosity is None:
			self.verbosity = ("--quiet" in frozen_config.myopts and 1 or \
				"--verbose" in frozen_config.myopts and 3 or 2)

		self.oneshot = "--oneshot" in frozen_config.myopts or \
			"--onlydeps" in frozen_config.myopts
		self.columns = "--columns" in frozen_config.myopts
		self.tree_display = "--tree" in frozen_config.myopts
		self.alphabetical = "--alphabetical" in frozen_config.myopts
		self.quiet = "--quiet" in frozen_config.myopts
		self.all_flags = self.verbosity == 3 or self.quiet
		self.print_use_string = self.verbosity != 1 or "--verbose" in frozen_config.myopts
		self.changelog = "--changelog" in frozen_config.myopts
		self.edebug = frozen_config.edebug
		self.no_restart = frozen_config._opts_no_restart.intersection(frozen_config.myopts)
		self.unordered_display = "--unordered-display" in frozen_config.myopts

		mywidth = 130
		if "COLUMNWIDTH" in frozen_config.settings:
			try:
				mywidth = int(frozen_config.settings["COLUMNWIDTH"])
			except ValueError as e:
				writemsg("!!! %s\n" % str(e), noiselevel=-1)
				writemsg("!!! Unable to parse COLUMNWIDTH='%s'\n" % \
					frozen_config.settings["COLUMNWIDTH"], noiselevel=-1)
				del e
		self.columnwidth = mywidth

		self.repo_display = _RepoDisplay(frozen_config.roots)
		self.trees = frozen_config.trees
		self.pkgsettings = frozen_config.pkgsettings
		self.target_root = frozen_config.target_root
		self.running_root = frozen_config._running_root
		self.roots = frozen_config.roots

		self.blocker_parents = dynamic_config._blocker_parents
		self.reinstall_nodes = dynamic_config._reinstall_nodes
		self.digraph = dynamic_config.digraph
		self.blocker_uninstalls = dynamic_config._blocker_uninstalls
		self.slot_pkg_map = dynamic_config._slot_pkg_map
		self.set_nodes = dynamic_config._set_nodes

		self.pkg_use_enabled = depgraph._pkg_use_enabled
		self.pkg = depgraph._pkg

# formats a size given in bytes nicely
def _format_size(mysize):
	if isinstance(mysize, basestring):
		return mysize
	if 0 != mysize % 1024:
		# Always round up to the next kB so that it doesn't show 0 kB when
		# some small file still needs to be fetched.
		mysize += 1024 - mysize % 1024
	mystr=str(mysize//1024)
	mycount=len(mystr)
	while (mycount > 3):
		mycount-=3
		mystr=mystr[:mycount]+","+mystr[mycount:]
	return mystr+" kB"

def display(depgraph, mylist, favorites=[], verbosity=None):

	conf = _DisplayConfig(depgraph, mylist, favorites, verbosity)

	changelogs=[]
	p=[]
	blockers = []
	counters = _PackageCounters()
	repo_display = conf.repo_display
	unsatisfied_blockers = []
	ordered_nodes = []
	for x in conf.mylist:
		if isinstance(x, Blocker):
			counters.blocks += 1
			if x.satisfied:
				ordered_nodes.append(x)
				counters.blocks_satisfied += 1
			else:
				unsatisfied_blockers.append(x)
		else:
			ordered_nodes.append(x)

	if conf.tree_display:
		display_list = _tree_display(conf, ordered_nodes)
	else:
		display_list = [(x, 0, True) for x in ordered_nodes]

	mylist = display_list
	for x in unsatisfied_blockers:
		mylist.append((x, 0, True))

	# files to fetch list - avoids counting a same file twice
	# in size display (verbose mode)
	myfetchlist=[]

	# Use this set to detect when all the "repoadd" strings are "[0]"
	# and disable the entire repo display in this case.
	repoadd_set = set()

	for mylist_index in range(len(mylist)):
		x, depth, ordered = mylist[mylist_index]
		pkg_type = x[0]
		myroot = x[1]
		pkg_key = x[2]
		portdb = conf.trees[myroot]["porttree"].dbapi
		vardb = conf.trees[myroot]["vartree"].dbapi
		pkgsettings = conf.pkgsettings[myroot]

		fetch=" "
		indent = " " * depth

		if isinstance(x, Blocker):
			if x.satisfied:
				blocker_style = "PKG_BLOCKER_SATISFIED"
				addl = "%s  %s  " % (colorize(blocker_style, "b"), fetch)
			else:
				blocker_style = "PKG_BLOCKER"
				addl = "%s  %s  " % (colorize(blocker_style, "B"), fetch)
			resolved = dep_expand(
				str(x.atom).lstrip("!"), mydb=vardb, settings=pkgsettings)
			if conf.columns and conf.quiet:
				addl += " " + colorize(blocker_style, str(resolved))
			else:
				addl = "[%s %s] %s%s" % \
					(colorize(blocker_style, "blocks"),
					addl, indent, colorize(blocker_style, str(resolved)))
			block_parents = conf.blocker_parents.parent_nodes(x)
			block_parents = set([pnode[2] for pnode in block_parents])
			block_parents = ", ".join(block_parents)
			if resolved!=x[2]:
				addl += colorize(blocker_style,
					" (\"%s\" is blocking %s)") % \
					(str(x.atom).lstrip("!"), block_parents)
			else:
				addl += colorize(blocker_style,
					" (is blocking %s)") % block_parents
			if isinstance(x, Blocker) and x.satisfied:
				if conf.columns:
					continue
				p.append(addl)
			else:
				blockers.append(addl)
		else:
			pkg_status = x[3]
			pkg_merge = ordered and pkg_status == "merge"
			if not pkg_merge and pkg_status == "merge":
				pkg_status = "nomerge"
			built = pkg_type != "ebuild"
			pkg = x
			metadata = pkg.metadata
			ebuild_path = None
			repo_name = pkg.repo
			if pkg.type_name == "ebuild":
				ebuild_path = portdb.findname(pkg.cpv, myrepo=repo_name)
				if ebuild_path is None:
					raise AssertionError(
						"ebuild not found for '%s'" % pkg.cpv)
				repo_path_real = os.path.dirname(os.path.dirname(
					os.path.dirname(ebuild_path)))
			else:
				repo_path_real = portdb.getRepositoryPath(repo_name)
			pkg_use = list(conf.pkg_use_enabled(pkg))
			if not pkg.built and pkg.operation == 'merge' and \
				'fetch' in pkg.metadata.restrict:
				fetch = red("F")
				if ordered:
					counters.restrict_fetch += 1
				if portdb.fetch_check(pkg_key, pkg_use, myrepo=pkg.repo):
					fetch = green("f")
					if ordered:
						counters.restrict_fetch_satisfied += 1

			#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.
			myoldbest = []
			myinslotlist = None
			installed_versions = vardb.match(cpv_getkey(pkg_key))
			if vardb.cpv_exists(pkg_key):
				addl="  "+yellow("R")+fetch+"  "
				if ordered:
					if pkg_merge:
						counters.reinst += 1
						if pkg_type == "binary":
							counters.binary += 1
					elif pkg_status == "uninstall":
						counters.uninst += 1
			# filter out old-style virtual matches
			elif installed_versions and \
				cpv_getkey(installed_versions[0]) == \
				cpv_getkey(pkg_key):
				myinslotlist = vardb.match(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 \
					cpv_getkey(myinslotlist[0]) != \
					cpv_getkey(pkg_key):
					myinslotlist = None
				if myinslotlist:
					myoldbest = myinslotlist[:]
					addl = "   " + fetch
					if not cpvequal(pkg_key,
						best([pkg_key] + myoldbest)):
						# Downgrade in slot
						addl += turquoise("U")+blue("D")
						if ordered:
							counters.downgrades += 1
							if pkg_type == "binary":
								counters.binary += 1
					else:
						# Update in slot
						addl += turquoise("U") + " "
						if ordered:
							counters.upgrades += 1
							if pkg_type == "binary":
								counters.binary += 1
				else:
					# New slot, mark it new.
					addl = " " + green("NS") + fetch + "  "
					myoldbest = vardb.match(cpv_getkey(pkg_key))
					if ordered:
						counters.newslot += 1
						if pkg_type == "binary":
							counters.binary += 1

				if conf.changelog:
					inst_matches = vardb.match(pkg.slot_atom)
					if inst_matches:
						ebuild_path_cl = ebuild_path
						if ebuild_path_cl is None:
							# binary package
							ebuild_path_cl = portdb.findname(pkg.cpv)

						if ebuild_path_cl is not None:
							changelogs.extend(_calc_changelog(
								ebuild_path_cl, inst_matches[0], pkg.cpv))
			else:
				addl = " " + green("N") + " " + fetch + "  "
				if ordered:
					counters.new += 1
					if pkg_type == "binary":
						counters.binary += 1

			verboseadd = ""
			repoadd = None

			if True:
				# USE flag display
				forced_flags = set()
				pkgsettings.setcpv(pkg) # for package.use.{mask,force}
				forced_flags.update(pkgsettings.useforce)
				forced_flags.update(pkgsettings.usemask)

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

				if myoldbest and myinslotlist:
					previous_cpv = myoldbest[0]
				else:
					previous_cpv = pkg.cpv
				if vardb.cpv_exists(previous_cpv):
					old_iuse, old_use = vardb.aux_get(
							previous_cpv, ["IUSE", "USE"])
					old_iuse = list(set(
						filter_iuse_defaults(old_iuse.split())))
					old_iuse.sort()
					old_use = old_use.split()
					is_new = False
				else:
					old_iuse = []
					old_use = []
					is_new = True

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

				use_expand = pkgsettings["USE_EXPAND"].lower().split()
				use_expand.sort()
				use_expand.reverse()
				use_expand_hidden = \
					pkgsettings["USE_EXPAND_HIDDEN"].lower().split()

				def map_to_use_expand(myvals, forcedFlags=False,
					removeHidden=True):
					ret = {}
					forced = {}
					for exp in use_expand:
						ret[exp] = []
						forced[exp] = set()
						for val in myvals[:]:
							if val.startswith(exp.lower()+"_"):
								if val in 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 forced_flags]
					if removeHidden:
						for exp in use_expand_hidden:
							ret.pop(exp, None)
					if forcedFlags:
						return ret, forced
					return ret

				# Prevent USE_EXPAND_HIDDEN flags from being hidden if they
				# are the only thing that triggered reinstallation.
				reinst_flags_map = {}
				reinstall_for_flags = conf.reinstall_nodes.get(pkg)
				reinst_expand_map = None
				if reinstall_for_flags:
					reinst_flags_map = map_to_use_expand(
						list(reinstall_for_flags), removeHidden=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(
					use_expand_hidden):
					use_expand_hidden = \
						set(use_expand_hidden).difference(
						reinst_expand_map)

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

				use_expand.sort()
				use_expand.insert(0, "USE")
				
				for key in use_expand:
					if key in use_expand_hidden:
						continue
					verboseadd += _create_use_string(conf, key.upper(),
						cur_iuse_map[key], iuse_forced[key],
						cur_use_map[key], old_iuse_map[key],
						old_use_map[key], is_new,
						reinst_flags_map.get(key))

			if conf.verbosity == 3:
				# size verbose
				mysize=0
				if pkg_type == "ebuild" and pkg_merge:
					try:
						myfilesdict = portdb.getfetchsizes(pkg_key,
							useflags=pkg_use, debug=conf.edebug)
					except InvalidDependString:
						# should have been masked before it was selected
						raise
					if myfilesdict is None:
						myfilesdict="[empty/missing/bad digest]"
					else:
						for myfetchfile in myfilesdict:
							if myfetchfile not in myfetchlist:
								mysize+=myfilesdict[myfetchfile]
								myfetchlist.append(myfetchfile)
						if ordered:
							counters.totalsize += mysize
					verboseadd += _format_size(mysize)

				# overlay verbose
				# assign index for a previous version in the same slot
				has_previous = False
				repo_name_prev = None
				slot_matches = vardb.match(pkg.slot_atom)
				if slot_matches:
					has_previous = True
					repo_name_prev = vardb.aux_get(slot_matches[0],
						["repository"])[0]

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

			xs = [cpv_getkey(pkg_key)] + \
				list(catpkgsplit(pkg_key)[2:])
			if xs[2] == "r0":
				xs[2] = ""
			else:
				xs[2] = "-" + xs[2]

			oldlp = conf.columnwidth - 30
			newlp = oldlp - 30

			# Convert myoldbest from a list to a string.
			if not myoldbest:
				myoldbest = ""
			else:
				for pos, key in enumerate(myoldbest):
					key = catpkgsplit(key)[2] + \
						"-" + catpkgsplit(key)[3]
					if key[-3:] == "-r0":
						key = key[:-3]
					myoldbest[pos] = key
				myoldbest = blue("["+", ".join(myoldbest)+"]")

			pkg_cp = xs[0]
			root_config = conf.roots[myroot]
			system_set = root_config.sets["system"]
			world_set  = root_config.sets["selected"]

			pkg_system = False
			pkg_world = False
			try:
				pkg_system = system_set.findAtomForPackage(pkg, modified_use=conf.pkg_use_enabled(pkg))
				pkg_world  = world_set.findAtomForPackage(pkg, modified_use=conf.pkg_use_enabled(pkg))
				if not (conf.oneshot or pkg_world) and \
					myroot == conf.target_root and \
					conf.favorites.findAtomForPackage(pkg, modified_use=conf.pkg_use_enabled(pkg)):
					# Maybe it will be added to world now.
					if create_world_atom(pkg, conf.favorites, root_config):
						pkg_world = True
			except InvalidDependString:
				# This is reported elsewhere if relevant.
				pass

			def pkgprint(pkg_str):
				if pkg_merge:
					if built:
						if pkg_system:
							return colorize("PKG_BINARY_MERGE_SYSTEM", pkg_str)
						elif pkg_world:
							return colorize("PKG_BINARY_MERGE_WORLD", pkg_str)
						else:
							return colorize("PKG_BINARY_MERGE", pkg_str)
					else:
						if pkg_system:
							return colorize("PKG_MERGE_SYSTEM", pkg_str)
						elif pkg_world:
							return colorize("PKG_MERGE_WORLD", pkg_str)
						else:
							return colorize("PKG_MERGE", pkg_str)
				elif pkg_status == "uninstall":
					return colorize("PKG_UNINSTALL", pkg_str)
				else:
					if pkg_system:
						return colorize("PKG_NOMERGE_SYSTEM", pkg_str)
					elif pkg_world:
						return colorize("PKG_NOMERGE_WORLD", pkg_str)
					else:
						return colorize("PKG_NOMERGE", pkg_str)

			if 'interactive' in pkg.metadata.properties and \
				pkg.operation == 'merge':
				addl = colorize("WARN", "I") + addl[1:]
				if ordered:
					counters.interactive += 1

			if x[1]!="/":
				if myoldbest:
					myoldbest +=" "
				if conf.columns:
					if conf.quiet:
						myprint=addl+" "+indent+pkgprint(pkg_cp)
						myprint=myprint+darkblue(" "+xs[1]+xs[2])+" "
						myprint=myprint+myoldbest
						myprint=myprint+darkgreen("to "+x[1])
						verboseadd = None
					else:
						if not pkg_merge:
							myprint = "[%s] %s%s" % \
								(pkgprint(pkg_status.ljust(13)),
								indent, pkgprint(pkg.cp))
						else:
							myprint = "[%s %s] %s%s" % \
								(pkgprint(pkg.type_name), addl,
								indent, pkgprint(pkg.cp))
						if (newlp-nc_len(myprint)) > 0:
							myprint=myprint+(" "*(newlp-nc_len(myprint)))
						myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
						if (oldlp-nc_len(myprint)) > 0:
							myprint=myprint+" "*(oldlp-nc_len(myprint))
						myprint=myprint+myoldbest
						myprint += darkgreen("to " + pkg.root)
				else:
					if not pkg_merge:
						myprint = "[%s] " % pkgprint(pkg_status.ljust(13))
					else:
						myprint = "[%s %s] " % (pkgprint(pkg_type), addl)
					myprint += indent + pkgprint(pkg_key) + " " + \
						myoldbest + darkgreen("to " + myroot)
			else:
				if conf.columns:
					if conf.quiet:
						myprint=addl+" "+indent+pkgprint(pkg_cp)
						myprint=myprint+" "+green(xs[1]+xs[2])+" "
						myprint=myprint+myoldbest
						verboseadd = None
					else:
						if not pkg_merge:
							myprint = "[%s] %s%s" % \
								(pkgprint(pkg_status.ljust(13)),
								indent, pkgprint(pkg.cp))
						else:
							myprint = "[%s %s] %s%s" % \
								(pkgprint(pkg.type_name), addl,
								indent, pkgprint(pkg.cp))
						if (newlp-nc_len(myprint)) > 0:
							myprint=myprint+(" "*(newlp-nc_len(myprint)))
						myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
						if (oldlp-nc_len(myprint)) > 0:
							myprint=myprint+(" "*(oldlp-nc_len(myprint)))
						myprint += myoldbest
				else:
					if not pkg_merge:
						myprint = "[%s] %s%s %s" % \
							(pkgprint(pkg_status.ljust(13)),
							indent, pkgprint(pkg.cpv),
							myoldbest)
					else:
						myprint = "[%s %s] %s%s %s" % \
							(pkgprint(pkg_type), addl, indent,
							pkgprint(pkg.cpv), myoldbest)

			if conf.columns and pkg.operation == "uninstall":
				continue
			p.append((myprint, verboseadd, repoadd))

			if not conf.tree_display and \
				conf.quiet and \
				not conf.no_restart and \
				pkg.root == conf.running_root.root and \
				match_from_list(
				PORTAGE_PACKAGE_ATOM, [pkg]) and \
				not conf.quiet:
				if not vardb.cpv_exists(pkg.cpv) or \
					'9999' in pkg.cpv or \
					'git' in pkg.inherited:
					if mylist_index < len(mylist) - 1:
						p.append(colorize("WARN", "*** Portage will stop merging at this point and reload itself,"))
						p.append(colorize("WARN", "    then resume the merge."))

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

	for x in p:
		if isinstance(x, basestring):
			writemsg_stdout("%s\n" % (x,), noiselevel=-1)
			continue

		myprint, verboseadd, repoadd = x

		if verboseadd:
			myprint += " " + verboseadd

		if show_repos and repoadd:
			myprint += " " + teal("[%s]" % repoadd)

		writemsg_stdout("%s\n" % (myprint,), noiselevel=-1)

	for x in blockers:
		writemsg_stdout("%s\n" % (x,), noiselevel=-1)

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

	if conf.changelog:
		writemsg_stdout('\n', noiselevel=-1)
		for revision,text in changelogs:
			writemsg_stdout(bold('*'+revision) + '\n' + text,
				noiselevel=-1)

	return os.EX_OK


def _create_use_string(conf, name, cur_iuse, iuse_forced, cur_use,
	old_iuse, old_use,
	is_new, reinst_flags):

	if not conf.print_use_string:
		return ""

	enabled = []
	if conf.alphabetical:
		disabled = enabled
		removed = enabled
	else:
		disabled = []
		removed = []
	cur_iuse = set(cur_iuse)
	enabled_flags = cur_iuse.intersection(cur_use)
	removed_iuse = set(old_iuse).difference(cur_iuse)
	any_iuse = cur_iuse.union(old_iuse)
	any_iuse = list(any_iuse)
	any_iuse.sort()
	for flag in any_iuse:
		flag_str = None
		isEnabled = False
		reinst_flag = reinst_flags and flag in reinst_flags
		if flag in enabled_flags:
			isEnabled = True
			if is_new or flag in old_use and \
				(conf.all_flags or reinst_flag):
				flag_str = red(flag)
			elif flag not in old_iuse:
				flag_str = yellow(flag) + "%*"
			elif flag not in old_use:
				flag_str = green(flag) + "*"
		elif flag in removed_iuse:
			if conf.all_flags or reinst_flag:
				flag_str = yellow("-" + flag) + "%"
				if flag in old_use:
					flag_str += "*"
				flag_str = "(" + flag_str + ")"
				removed.append(flag_str)
			continue
		else:
			if is_new or flag in old_iuse and \
				flag not in old_use and \
				(conf.all_flags or reinst_flag):
				flag_str = blue("-" + flag)
			elif flag not in old_iuse:
				flag_str = yellow("-" + flag)
				if flag not in iuse_forced:
					flag_str += "%"
			elif flag in old_use:
				flag_str = green("-" + flag) + "*"
		if flag_str:
			if flag in iuse_forced:
				flag_str = "(" + flag_str + ")"
			if isEnabled:
				enabled.append(flag_str)
			else:
				disabled.append(flag_str)

	if conf.alphabetical:
		ret = " ".join(enabled)
	else:
		ret = " ".join(enabled + disabled + removed)
	if ret:
		ret = '%s="%s" ' % (name, ret)
	return ret


def _tree_display(conf, mylist):

	# If there are any Uninstall instances, add the
	# corresponding blockers to the digraph.
	mygraph = conf.digraph.copy()

	executed_uninstalls = set(node for node in mylist \
		if isinstance(node, Package) and node.operation == "unmerge")

	for uninstall in conf.blocker_uninstalls.leaf_nodes():
		uninstall_parents = \
			conf.blocker_uninstalls.parent_nodes(uninstall)
		if not uninstall_parents:
			continue

		# Remove the corresponding "nomerge" node and substitute
		# the Uninstall node.
		inst_pkg = conf.pkg(uninstall.cpv, "installed",
			uninstall.root_config, installed=True)

		try:
			mygraph.remove(inst_pkg)
		except KeyError:
			pass

		try:
			inst_pkg_blockers = conf.blocker_parents.child_nodes(inst_pkg)
		except KeyError:
			inst_pkg_blockers = []

		# Break the Package -> Uninstall edges.
		mygraph.remove(uninstall)

		# Resolution of a package's blockers
		# depend on it's own uninstallation.
		for blocker in inst_pkg_blockers:
			mygraph.add(uninstall, blocker)

		# Expand Package -> Uninstall edges into
		# Package -> Blocker -> Uninstall edges.
		for blocker in uninstall_parents:
			mygraph.add(uninstall, blocker)
			for parent in conf.blocker_parents.parent_nodes(blocker):
				if parent != inst_pkg:
					mygraph.add(blocker, parent)

		# If the uninstall task did not need to be executed because
		# of an upgrade, display Blocker -> Upgrade edges since the
		# corresponding Blocker -> Uninstall edges will not be shown.
		upgrade_node = \
			conf.slot_pkg_map[uninstall.root].get(uninstall.slot_atom)
		if upgrade_node is not None and \
			uninstall not in executed_uninstalls:
			for blocker in uninstall_parents:
				mygraph.add(upgrade_node, blocker)

	if conf.unordered_display:
		display_list = _unordered_tree_display(mygraph, mylist)
	else:
		display_list = _ordered_tree_display(conf, mygraph, mylist)

	_prune_tree_display(display_list)

	return display_list

def _unordered_tree_display(mygraph, mylist):
	display_list = []
	seen_nodes = set()

	def print_node(node, depth):

		if node in seen_nodes:
			pass
		else:
			seen_nodes.add(node)

			if isinstance(node, (Blocker, Package)):
				display_list.append((node, depth, True))
			else:
				depth = -1

			for child_node in mygraph.child_nodes(node):
				print_node(child_node, depth + 1)

	for root_node in mygraph.root_nodes():
		print_node(root_node, 0)

	return display_list

def _ordered_tree_display(conf, mygraph, mylist):
	depth = 0
	shown_edges = set()
	tree_nodes = []
	display_list = []

	for x in mylist:
		depth = len(tree_nodes)
		while depth and x not in \
			mygraph.child_nodes(tree_nodes[depth-1]):
				depth -= 1
		if depth:
			tree_nodes = tree_nodes[:depth]
			tree_nodes.append(x)
			display_list.append((x, depth, True))
			shown_edges.add((x, tree_nodes[depth-1]))
		else:
			traversed_nodes = set() # prevent endless circles
			traversed_nodes.add(x)
			def add_parents(current_node, ordered):
				parent_nodes = None
				# Do not traverse to parents if this node is an
				# an argument or a direct member of a set that has
				# been specified as an argument (system or world).
				if current_node not in conf.set_nodes:
					parent_nodes = mygraph.parent_nodes(current_node)
				if parent_nodes:
					child_nodes = set(mygraph.child_nodes(current_node))
					selected_parent = None
					# First, try to avoid a direct cycle.
					for node in parent_nodes:
						if not isinstance(node, (Blocker, Package)):
							continue
						if node not in traversed_nodes and \
							node not in child_nodes:
							edge = (current_node, node)
							if edge in shown_edges:
								continue
							selected_parent = node
							break
					if not selected_parent:
						# A direct cycle is unavoidable.
						for node in parent_nodes:
							if not isinstance(node, (Blocker, Package)):
								continue
							if node not in traversed_nodes:
								edge = (current_node, node)
								if edge in shown_edges:
									continue
								selected_parent = node
								break
					if selected_parent:
						shown_edges.add((current_node, selected_parent))
						traversed_nodes.add(selected_parent)
						add_parents(selected_parent, False)
				display_list.append((current_node,
					len(tree_nodes), ordered))
				tree_nodes.append(current_node)
			tree_nodes = []
			add_parents(x, True)

	return display_list

def _prune_tree_display(display_list):
	last_merge_depth = 0
	for i in range(len(display_list) - 1, -1, -1):
		node, depth, ordered = display_list[i]
		if not ordered and depth == 0 and i > 0 \
			and node == display_list[i-1][0] and \
			display_list[i-1][1] == 0:
			# An ordered node got a consecutive duplicate
			# when the tree was being filled in.
			del display_list[i]
			continue
		if ordered and isinstance(node, Package) \
			and node.operation in ('merge', 'uninstall'):
			last_merge_depth = depth
			continue
		if depth >= last_merge_depth or \
			i < len(display_list) - 1 and \
			depth >= display_list[i+1][1]:
				del display_list[i]

def _calc_changelog(ebuildpath,current,next):
	if ebuildpath == None or not os.path.exists(ebuildpath):
		return []
	current = '-'.join(catpkgsplit(current)[1:])
	if current.endswith('-r0'):
		current = current[:-3]
	next = '-'.join(catpkgsplit(next)[1:])
	if next.endswith('-r0'):
		next = next[:-3]
	changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
	try:
		changelog = codecs.open(_unicode_encode(changelogpath,
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'], errors='replace'
		).read()
	except SystemExit:
		raise # Needed else can't exit
	except:
		return []
	divisions = _find_changelog_tags(changelog)
	#print 'XX from',current,'to',next
	#for div,text in divisions: print 'XX',div
	# skip entries for all revisions above the one we are about to emerge
	for i in range(len(divisions)):
		if divisions[i][0]==next:
			divisions = divisions[i:]
			break
	# find out how many entries we are going to display
	for i in range(len(divisions)):
		if divisions[i][0]==current:
			divisions = divisions[:i]
			break
	else:
	    # couldnt find the current revision in the list. display nothing
		return []
	return divisions

def _find_changelog_tags(changelog):
	divs = []
	release = None
	while 1:
		match = re.search(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?\n',changelog,re.M)
		if match is None:
			if release is not None:
				divs.append((release,changelog))
			return divs
		if release is not None:
			divs.append((release,changelog[:match.start()]))
		changelog = changelog[match.end():]
		release = match.group(1)
		if release.endswith('.ebuild'):
			release = release[:-7]
		if release.endswith('-r0'):
			release = release[:-3]
