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

from __future__ import unicode_literals

import portage
from portage.dep import Atom, _get_useflag_re
from portage.eapi import _get_eapi_attrs

def expand_new_virt(vardb, atom):
	"""
	Iterate over the recursively expanded RDEPEND atoms of
	a new-style virtual. If atom is not a new-style virtual
	or it does not match an installed package then it is
	yielded without any expansion.
	"""
	if not isinstance(atom, Atom):
		atom = Atom(atom)

	if not atom.cp.startswith("virtual/"):
		yield atom
		return

	traversed = set()
	stack = [atom]

	while stack:
		atom = stack.pop()
		if atom.blocker or \
			not atom.cp.startswith("virtual/"):
			yield atom
			continue

		matches = vardb.match(atom)
		if not (matches and matches[-1].startswith("virtual/")):
			yield atom
			continue

		virt_cpv = matches[-1]
		if virt_cpv in traversed:
			continue

		traversed.add(virt_cpv)
		eapi, iuse, rdepend, use = vardb.aux_get(virt_cpv,
			["EAPI", "IUSE", "RDEPEND", "USE"])
		if not portage.eapi_is_supported(eapi):
			yield atom
			continue

		eapi_attrs = _get_eapi_attrs(eapi)
		# Validate IUSE and IUSE, for early detection of vardb corruption.
		useflag_re = _get_useflag_re(eapi)
		valid_iuse = []
		for x in iuse.split():
			if x[:1] in ("+", "-"):
				x = x[1:]
			if useflag_re.match(x) is not None:
				valid_iuse.append(x)
		valid_iuse = frozenset(valid_iuse)

		if eapi_attrs.iuse_effective:
			iuse_implicit_match = vardb.settings._iuse_effective_match
		else:
			iuse_implicit_match = vardb.settings._iuse_implicit_match

		valid_use = []
		for x in use.split():
			if x in valid_iuse or iuse_implicit_match(x):
				valid_use.append(x)
		valid_use = frozenset(valid_use)

		success, atoms = portage.dep_check(rdepend,
			None, vardb.settings, myuse=valid_use,
			myroot=vardb.settings['EROOT'],
			trees={vardb.settings['EROOT']:{"porttree":vardb.vartree,
			"vartree":vardb.vartree}})

		if success:
			stack.extend(atoms)
		else:
			yield atom
