# Copyright 2017-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from portage.tests import TestCase
from portage.tests.resolver.ResolverPlayground import (
	ResolverPlayground,
	ResolverPlaygroundTestCase,
)

class VirtualMinimizeChildrenTestCase(TestCase):

	def testVirtualMinimizeChildren(self):
		ebuilds = {
			'app-misc/bar-1': {
				'EAPI': '6',
				'RDEPEND': 'virtual/foo'
			},
			'virtual/foo-1': {
				'EAPI': '6',
				'RDEPEND': '|| ( app-misc/A app-misc/B ) || ( app-misc/B app-misc/C )'
			},
			'app-misc/A-1': {
				'EAPI': '6',
			},
			'app-misc/B-1': {
				'EAPI': '6',
			},
			'app-misc/C-1': {
				'EAPI': '6',
			},
		}

		test_cases = (
			# Test bug 632026, where we want to minimize the number of
			# packages chosen to satisfy overlapping || deps like
			# "|| ( foo bar ) || ( bar baz )".
			ResolverPlaygroundTestCase(
				['app-misc/bar'],
				success=True,
				mergelist=[
					'app-misc/B-1',
					'virtual/foo-1',
					'app-misc/bar-1',
				],
			),
		)

		playground = ResolverPlayground(debug=False,
			ebuilds=ebuilds)

		try:
			for test_case in test_cases:
				playground.run_TestCase(test_case)
				self.assertEqual(test_case.test_success, True,
					test_case.fail_msg)
		finally:
			playground.debug = False
			playground.cleanup()

		# If app-misc/A and app-misc/C are installed then
		# that choice should be preferred over app-misc/B.
		installed = {
			'app-misc/A-1': {
				'EAPI': '6',
			},
			'app-misc/C-1': {
				'EAPI': '6',
			},
		}

		test_cases = (
			ResolverPlaygroundTestCase(
				['app-misc/bar'],
				success=True,
				mergelist=[
					'virtual/foo-1',
					'app-misc/bar-1',
				],
			),
		)

		playground = ResolverPlayground(debug=False,
			ebuilds=ebuilds, installed=installed)

		try:
			for test_case in test_cases:
				playground.run_TestCase(test_case)
				self.assertEqual(test_case.test_success, True,
					test_case.fail_msg)
		finally:
			playground.debug = False
			playground.cleanup()

	def testOverlapSlotConflict(self):
		ebuilds = {
			'app-misc/bar-1': {
				'EAPI': '6',
				'RDEPEND': 'virtual/foo'
			},
			'virtual/foo-1': {
				'EAPI': '6',
				'RDEPEND': '|| ( app-misc/A >=app-misc/B-2 ) || ( <app-misc/B-2 app-misc/C )'
			},
			'app-misc/A-1': {
				'EAPI': '6',
			},
			'app-misc/B-2': {
				'EAPI': '6',
			},
			'app-misc/B-1': {
				'EAPI': '6',
			},
			'app-misc/C-1': {
				'EAPI': '6',
			},
		}

		test_cases = (
			# Here the ( >=app-misc/B-2 <app-misc/B-2 ) choice is not satisfiable.
			ResolverPlaygroundTestCase(
				['app-misc/bar'],
				success=True,
				ambiguous_merge_order=True,
				mergelist=[
					(
						'app-misc/C-1',
						'app-misc/A-1',
					),
					'virtual/foo-1',
					'app-misc/bar-1',
				]
			),
		)

		playground = ResolverPlayground(debug=False,
			ebuilds=ebuilds)

		try:
			for test_case in test_cases:
				playground.run_TestCase(test_case)
				self.assertEqual(test_case.test_success, True,
					test_case.fail_msg)
		finally:
			playground.debug = False
			playground.cleanup()

	def testVirtualPackageManager(self):
		ebuilds = {
			'app-admin/perl-cleaner-2.25': {
				'RDEPEND': '''
					|| (
						( sys-apps/portage app-portage/portage-utils )
						sys-apps/pkgcore
						sys-apps/paludis
					)'''
			},
			'app-portage/portage-utils-0.64': {},
			'sys-apps/paludis-2.6.0': {},
			'sys-apps/portage-2.3.19-r1': {},
			'virtual/package-manager-0': {
				'RDEPEND': '''
					|| (
						sys-apps/portage
						sys-apps/paludis
						sys-apps/pkgcore
					)'''
			},
		}

		test_cases = (
			# Test bug 645002, where paludis was selected to satisfy a
			# perl-cleaner dependency because that choice contained fewer
			# packages than the ( portage portage-utils ) choice which
			# should have been preferred according to the order of
			# choices specified in the ebuild.
			ResolverPlaygroundTestCase(
				[
					'app-admin/perl-cleaner',
					'virtual/package-manager',
				],
				all_permutations=True,
				success=True,
				ambiguous_merge_order=True,
				mergelist=(
					(
						'sys-apps/portage-2.3.19-r1',
						'app-portage/portage-utils-0.64',
						'app-admin/perl-cleaner-2.25',
						'virtual/package-manager-0',
					),
				)
			),
			# Test paludis preference. In this case, if paludis is not
			# included in the argument atoms then the result varies
			# depending on whether the app-admin/perl-cleaner or
			# virtual/package-manager dependencies are evaluated first!
			# Therefore, include paludis in the argument atoms.
			ResolverPlaygroundTestCase(
				[
					'app-admin/perl-cleaner',
					'virtual/package-manager',
					'sys-apps/paludis',
				],
				all_permutations=True,
				success=True,
				ambiguous_merge_order=True,
				mergelist=(
					'sys-apps/paludis-2.6.0',
					(
						'app-admin/perl-cleaner-2.25',
						'virtual/package-manager-0',
					),
				)
			),
		)

		playground = ResolverPlayground(debug=False, ebuilds=ebuilds)

		try:
			for test_case in test_cases:
				playground.run_TestCase(test_case)
				self.assertEqual(test_case.test_success, True,
					test_case.fail_msg)
		finally:
			playground.debug = False
			playground.cleanup()

	def testVirtualDevManager(self):
		ebuilds = {
			'sys-fs/eudev-3.1.5': {},
			'sys-fs/static-dev-0.1': {},
			'sys-fs/udev-233': {},
			'virtual/dev-manager-0': {
				'RDEPEND': '''
					|| (
						virtual/udev
						sys-fs/static-dev
					)'''
			},
			'virtual/udev-0': {
				'RDEPEND': '''
					|| (
						>=sys-fs/eudev-2.1.1
						>=sys-fs/udev-217
					)'''
			},
		}

		test_cases = (
			# Test bug 645190, where static-dev was pulled in instead
			# of eudev.
			ResolverPlaygroundTestCase(
				[
					'virtual/dev-manager',
				],
				success=True,
				mergelist=(
					'sys-fs/eudev-3.1.5',
					'virtual/udev-0',
					'virtual/dev-manager-0',
				),
			),
			# Test static-dev preference.
			ResolverPlaygroundTestCase(
				[
					'sys-fs/static-dev',
					'virtual/dev-manager',
				],
				all_permutations=True,
				success=True,
				mergelist=(
					'sys-fs/static-dev-0.1',
					'virtual/dev-manager-0',
				),
			),
		)

		playground = ResolverPlayground(debug=False, ebuilds=ebuilds)

		try:
			for test_case in test_cases:
				playground.run_TestCase(test_case)
				self.assertEqual(test_case.test_success, True,
					test_case.fail_msg)
		finally:
			playground.debug = False
			playground.cleanup()
