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

from __future__ import unicode_literals

import collections
from itertools import chain
import sys

from portage import _encodings, _unicode_encode
from portage.output import red
from portage.util import cmp_sort_key
from portage.output import blue

class UseFlagDisplay(object):

	__slots__ = ('name', 'enabled', 'forced')

	def __init__(self, name, enabled, forced):
		self.name = name
		self.enabled = enabled
		self.forced = forced

	def __str__(self):
		s = self.name
		if self.enabled:
			s = red(s)
		else:
			s = '-' + s
			s = blue(s)
		if self.forced:
			s = '(%s)' % s
		return s

	if sys.hexversion < 0x3000000:

		__unicode__ = __str__

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

	def _cmp_combined(a, b):
		"""
		Sort by name, combining enabled and disabled flags.
		"""
		return (a.name > b.name) - (a.name < b.name)

	sort_combined = cmp_sort_key(_cmp_combined)
	del _cmp_combined

	def _cmp_separated(a, b):
		"""
		Sort by name, separating enabled flags from disabled flags.
		"""
		enabled_diff = b.enabled - a.enabled
		if enabled_diff:
			return enabled_diff
		return (a.name > b.name) - (a.name < b.name)

	sort_separated = cmp_sort_key(_cmp_separated)
	del _cmp_separated


_flag_info = collections.namedtuple('_flag_info', ('flag', 'display'))


def pkg_use_display(pkg, opts, modified_use=None):
	settings = pkg.root_config.settings
	use_expand = pkg.use.expand
	use_expand_hidden = pkg.use.expand_hidden
	alphabetical_use = '--alphabetical' in opts
	forced_flags = set(chain(pkg.use.force,
		pkg.use.mask))
	if modified_use is None:
		use = set(pkg.use.enabled)
	else:
		use = set(modified_use)
	use.discard(settings.get('ARCH'))
	use_expand_flags = set()
	use_enabled = {}
	use_disabled = {}
	for varname in use_expand:
		flag_prefix = varname.lower() + "_"
		for f in use:
			if f.startswith(flag_prefix):
				use_expand_flags.add(f)
				use_enabled.setdefault(
					varname.upper(), []).append(
						_flag_info(f, f[len(flag_prefix):]))

		for f in pkg.iuse.all:
			if f.startswith(flag_prefix):
				use_expand_flags.add(f)
				if f not in use:
					use_disabled.setdefault(
						varname.upper(), []).append(
							_flag_info(f, f[len(flag_prefix):]))

	var_order = set(use_enabled)
	var_order.update(use_disabled)
	var_order = sorted(var_order)
	var_order.insert(0, 'USE')
	use.difference_update(use_expand_flags)
	use_enabled['USE'] = list(_flag_info(f, f) for f in use)
	use_disabled['USE'] = []

	for f in pkg.iuse.all:
		if f not in use and \
			f not in use_expand_flags:
			use_disabled['USE'].append(_flag_info(f, f))

	flag_displays = []
	for varname in var_order:
		if varname.lower() in use_expand_hidden:
			continue
		flags = []
		for f in use_enabled.get(varname, []):
			flags.append(UseFlagDisplay(f.display, True, f.flag in forced_flags))
		for f in use_disabled.get(varname, []):
			flags.append(UseFlagDisplay(f.display, False, f.flag in forced_flags))
		if alphabetical_use:
			flags.sort(key=UseFlagDisplay.sort_combined)
		else:
			flags.sort(key=UseFlagDisplay.sort_separated)
		# Use unicode_literals to force unicode format string so
		# that UseFlagDisplay.__unicode__() is called in python2.
		flag_displays.append('%s="%s"' % (varname,
			' '.join("%s" % (f,) for f in flags)))

	return ' '.join(flag_displays)
