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

from __future__ import print_function

import logging

import portage
from portage.output import colorize

def display_preserved_libs(vardb):

	MAX_DISPLAY = 3

	plibdata = vardb._plib_registry.getPreservedLibs()
	linkmap = vardb._linkmap
	consumer_map = {}
	owners = {}

	try:
		linkmap.rebuild()
	except portage.exception.CommandNotFound as e:
		portage.util.writemsg_level("!!! Command Not Found: %s\n" % (e,),
			level=logging.ERROR, noiselevel=-1)
	else:
		search_for_owners = set()
		for cpv in plibdata:
			internal_plib_keys = set(linkmap._obj_key(f) \
				for f in plibdata[cpv])
			for f in plibdata[cpv]:
				if f in consumer_map:
					continue
				consumers = []
				for c in linkmap.findConsumers(f, greedy=False):
					# Filter out any consumers that are also preserved libs
					# belonging to the same package as the provider.
					if linkmap._obj_key(c) not in internal_plib_keys:
						consumers.append(c)
				consumers.sort()
				consumer_map[f] = consumers
				search_for_owners.update(consumers[:MAX_DISPLAY+1])

		owners = {}
		for f in search_for_owners:
			owner_set = set()
			for owner in linkmap.getOwners(f):
				owner_dblink = vardb._dblink(owner)
				if owner_dblink.exists():
					owner_set.add(owner_dblink)
			if owner_set:
				owners[f] = owner_set

	all_preserved = set()
	all_preserved.update(*plibdata.values())

	for cpv in plibdata:
		print(colorize("WARN", ">>>") + " package: %s" % cpv)
		samefile_map = {}
		for f in plibdata[cpv]:
			obj_key = linkmap._obj_key(f)
			alt_paths = samefile_map.get(obj_key)
			if alt_paths is None:
				alt_paths = set()
				samefile_map[obj_key] = alt_paths
			alt_paths.add(f)

		for alt_paths in samefile_map.values():
			alt_paths = sorted(alt_paths)
			for p in alt_paths:
				print(colorize("WARN", " * ") + " - %s" % (p,))
			f = alt_paths[0]
			consumers = consumer_map.get(f, [])
			consumers_non_preserved = [c for c in consumers
				if c not in all_preserved]
			if consumers_non_preserved:
				# Filter the consumers that are preserved libraries, since
				# they don't need to be rebuilt (see bug #461908).
				consumers = consumers_non_preserved

			if len(consumers) == MAX_DISPLAY + 1:
				# Display 1 extra consumer, instead of displaying
				# "used by 1 other files".
				max_display = MAX_DISPLAY + 1
			else:
				max_display = MAX_DISPLAY
			for c in consumers[:max_display]:
				if c in all_preserved:
					# The owner is displayed elsewhere due to having
					# its libs preserved, so distinguish this special
					# case (see bug #461908).
					owners_desc = "preserved"
				else:
					owners_desc = ", ".join(x.mycpv for x in owners.get(c, []))
				print(colorize("WARN", " * ") + "     used by %s (%s)" % \
					(c, owners_desc))
			if len(consumers) > max_display:
				print(colorize("WARN", " * ") + "     used by %d other files" %
					(len(consumers) - max_display))
