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

"""Contains private support functions for the Display class
in output.py
"""

from __future__ import unicode_literals

__all__ = (
	)

import io
import re
import sys

from portage import os
from portage import _encodings, _unicode_encode
from portage._sets.base import InternalPackageSet
from portage.localization import localized_size
from portage.output import (blue, bold, colorize, create_color_func,
	green, red, teal, turquoise, yellow)
bad = create_color_func("BAD")
from portage.util import shlex_split, writemsg
from portage.util.SlotObject import SlotObject
from portage.versions import catpkgsplit

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


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


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 portdir:
				repo_paths.add(portdir)
			overlays = root_config.settings.get("PORTDIR_OVERLAY")
			if overlays:
				repo_paths.update(shlex_split(overlays))
		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" % localized_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.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

		if "--quiet-repo-display" in frozen_config.myopts:
			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.package_tracker = dynamic_config._package_tracker
		self.set_nodes = dynamic_config._set_nodes

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


def _create_use_string(conf, name, cur_iuse, iuse_forced, cur_use,
	old_iuse, old_use,
	is_new, feature_flags, 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 feature_flags:
				flag_str = "{" + flag_str + "}"
			elif 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 = next(conf.package_tracker.match(
			uninstall.root, uninstall.slot_atom), None)

		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]

	changelogdir = os.path.dirname(ebuildpath)
	changelogs = ['ChangeLog']
	# ChangeLog-YYYY (see bug #389611)
	changelogs.extend(sorted((fn for fn in os.listdir(changelogdir)
		if fn.startswith('ChangeLog-')), reverse=True))

	divisions = []
	found_current = False
	for fn in changelogs:
		changelogpath = os.path.join(changelogdir, fn)
		try:
			with io.open(_unicode_encode(changelogpath,
				encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content'],
				errors='replace') as f:
				changelog = f.read()
		except EnvironmentError:
			return []
		for node in _find_changelog_tags(changelog):
			if node[0] == current:
				found_current = True
				break
			else:
				divisions.append(node)
		if found_current:
			break

	if not found_current:
		return []

	#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
	later_rev_index = None
	for i, node in enumerate(divisions):
		if node[0] == next:
			if later_rev_index is not None:
				first_node = divisions[later_rev_index]
				# Discard the later revision and the first ChangeLog entry
				# that follows it. We want to display all the entries after
				# that first entry, as discussed in bug #373009.
				trimmed_lines = []
				iterator = iter(first_node[1])
				for l in iterator:
					if not l:
						# end of the first entry that's discarded
						break
				first_node = (None, list(iterator))
				divisions = [first_node] + divisions[later_rev_index+1:]
			break
		if node[0] is not None:
			later_rev_index = i

	output = []
	prev_blank = False
	prev_rev = False
	for rev, lines in divisions:
		if rev is not None:
			if not (prev_blank or prev_rev):
				output.append("\n")
			output.append(bold('*' + rev) + '\n')
			prev_rev = True
			prev_blank = False
		if lines:
			prev_rev = False
			if not prev_blank:
				output.append("\n")
			for l in lines:
				output.append(l + "\n")
			output.append("\n")
			prev_blank = True
	return output

def _strip_header_comments(lines):
	# strip leading and trailing blank or header/comment lines
	i = 0
	while i < len(lines) and (not lines[i] or lines[i][:1] == "#"):
		i += 1
	if i:
		lines = lines[i:]
	while lines and (not lines[-1] or lines[-1][:1] == "#"):
		lines.pop()
	return lines

def _find_changelog_tags(changelog):
	divs = []
	if not changelog:
		return divs
	release = None
	release_end = 0
	for match in re.finditer(r'^\*\ ?([-a-zA-Z0-9_.+]*)(?:\ .*)?$',
		changelog, re.M):
		divs.append((release, _strip_header_comments(
			changelog[release_end:match.start()].splitlines())))
		release_end = match.end()
		release = match.group(1)
		if release.endswith('.ebuild'):
			release = release[:-7]
		if release.endswith('-r0'):
			release = release[:-3]

	divs.append((release,
		_strip_header_comments(changelog[release_end:].splitlines())))
	return divs

class PkgInfo(object):
	"""Simple class to hold instance attributes for current
	information about the pkg being printed.
	"""
	
	__slots__ = ("attr_display", "built", "cp",
		"ebuild_path", "fetch_symbol", "merge",
		"oldbest", "oldbest_list", "operation", "ordered", "previous_pkg",
		"repo_name", "repo_path_real", "slot", "sub_slot", "system", "use", "ver", "world")


	def __init__(self):
		self.built = False
		self.cp = ''
		self.ebuild_path = ''
		self.fetch_symbol = ''
		self.merge = ''
		self.oldbest = ''
		self.oldbest_list = []
		self.operation = ''
		self.ordered = False
		self.previous_pkg = None
		self.repo_path_real = ''
		self.repo_name = ''
		self.slot = ''
		self.sub_slot = ''
		self.system = False
		self.use = ''
		self.ver = ''
		self.world = False
		self.attr_display = PkgAttrDisplay()

class PkgAttrDisplay(SlotObject):

	__slots__ = ("downgrade", "fetch_restrict", "fetch_restrict_satisfied",
		"force_reinstall",
		"interactive", "mask", "new", "new_slot", "new_version", "replace")

	def __str__(self):
		output = []

		if self.interactive:
			output.append(colorize("WARN", "I"))
		else:
			output.append(" ")

		if self.new or self.force_reinstall:
			if self.force_reinstall:
				output.append(red("r"))
			else:
				output.append(green("N"))
		else:
			output.append(" ")

		if self.new_slot or self.replace:
			if self.replace:
				output.append(yellow("R"))
			else:
				output.append(green("S"))
		else:
			output.append(" ")

		if self.fetch_restrict or self.fetch_restrict_satisfied:
			if self.fetch_restrict_satisfied:
				output.append(green("f"))
			else:
				output.append(red("F"))
		else:
			output.append(" ")

		if self.new_version:
			output.append(turquoise("U"))
		else:
			output.append(" ")

		if self.downgrade:
			output.append(blue("D"))
		else:
			output.append(" ")

		if self.mask is not None:
			output.append(self.mask)

		return "".join(output)

	if sys.hexversion < 0x3000000:

		__unicode__ = __str__

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