#!/usr/bin/env python
# Copyright 2010-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# Note: We don't want to import portage modules directly because we do things
# like run the testsuite through multiple versions of python.

"""Helper script to run portage unittests against different python versions.

Note: Any additional arguments will be passed down directly to the underlying
unittest runner.  This lets you select specific tests to execute.
"""

from __future__ import print_function

import argparse
import os
import shutil
import subprocess
import sys
import tempfile


# These are the versions we fully support and require to pass tests.
PYTHON_SUPPORTED_VERSIONS = [
	'2.7',
	'3.4',
	'3.5',
	'3.6'
]
# The rest are just "nice to have".
PYTHON_NICE_VERSIONS = [
	'pypy',
	'3.7'
]

EPREFIX = os.environ.get('PORTAGE_OVERRIDE_EPREFIX', '/')


class Colors(object):
	"""Simple object holding color constants."""

	_COLORS_YES = ('y', 'yes', 'true')
	_COLORS_NO = ('n', 'no', 'false')

	WARN = GOOD = BAD = NORMAL = ''

	def __init__(self, colorize=None):
		if colorize is None:
			nocolors = os.environ.get('NOCOLOR', 'false')
			# Ugh, look away, for here we invert the world!
			if nocolors in self._COLORS_YES:
				colorize = False
			elif nocolors in self._COLORS_NO:
				colorize = True
			else:
				raise ValueError('$NOCOLORS is invalid: %s' % nocolors)
		else:
			if colorize in self._COLORS_YES:
				colorize = True
			elif colorize in self._COLORS_NO:
				colorize = False
			else:
				raise ValueError('--colors is invalid: %s' % colorize)

		if colorize:
			self.WARN = '\033[1;33m'
			self.GOOD = '\033[1;32m'
			self.BAD = '\033[1;31m'
			self.NORMAL = '\033[0m'


def get_python_executable(ver):
	"""Find the right python executable for |ver|"""
	if ver in ('pypy', 'pypy3'):
		prog = ver
	else:
		prog = 'python' + ver
	return os.path.join(EPREFIX, 'usr', 'bin', prog)


def get_parser():
	"""Return a argument parser for this module"""
	epilog = """Examples:
List all the available unittests.
$ %(prog)s --list

Run against specific versions of python.
$ %(prog)s --python-versions '2.7 3.3'

Run just one unittest.
$ %(prog)s lib/portage/tests/xpak/test_decodeint.py
"""
	parser = argparse.ArgumentParser(
		description=__doc__,
		formatter_class=argparse.RawDescriptionHelpFormatter,
		epilog=epilog)
	parser.add_argument('--keep-temp', default=False, action='store_true',
		help='Do not delete the temporary directory when exiting')
	parser.add_argument('--color', type=str, default=None,
		help='Whether to use colorized output (default is auto)')
	parser.add_argument('--python-versions', action='append',
		help='Versions of python to test (default is test available)')
	return parser


def main(argv):
	parser = get_parser()
	opts, args = parser.parse_known_args(argv)
	colors = Colors(colorize=opts.color)

	# Figure out all the versions we want to test.
	if opts.python_versions is None:
		ignore_missing = True
		pyversions = PYTHON_SUPPORTED_VERSIONS + PYTHON_NICE_VERSIONS
	else:
		ignore_missing = False
		pyversions = []
		for ver in opts.python_versions:
			if ver == 'supported':
				pyversions.extend(PYTHON_SUPPORTED_VERSIONS)
			else:
				pyversions.extend(ver.split())

	here = os.path.dirname(__file__)
	run_path = os.path.join(here, 'lib/repoman/tests/runTests.py')
	tempdir = None
	try:
		# Set up a single tempdir for all the tests to use.
		# This way we know the tests won't leak things on us.
		tempdir = tempfile.mkdtemp(prefix='repoman.runtests.')
		os.environ['TMPDIR'] = tempdir

		# Actually test those versions now.
		statuses = []
		for ver in pyversions:
			prog = get_python_executable(ver)
			cmd = [prog, '-b', '-Wd', run_path] + args
			if os.access(prog, os.X_OK):
				print('%sTesting with Python %s...%s' %
					(colors.GOOD, ver, colors.NORMAL))
				statuses.append((ver, subprocess.call(cmd)))
			elif not ignore_missing:
				print('%sCould not find requested Python %s%s' %
					(colors.BAD, ver, colors.NORMAL))
				statuses.append((ver, 1))
			else:
				print('%sSkip Python %s...%s' %
					(colors.WARN, ver, colors.NORMAL))
			print()
	finally:
		if tempdir is not None:
			if opts.keep_temp:
				print('Temporary directory left behind:\n%s' % tempdir)
			else:
				# Nuke our tempdir and anything that might be under it.
				shutil.rmtree(tempdir, True)

	# Then summarize it all.
	print('\nSummary:\n')
	width = 10
	header = '| %-*s | %s' % (width, 'Version', 'Status')
	print('%s\n|%s' % (header, '-' * (len(header) - 1)))
	exit_status = 0
	for ver, status in statuses:
		exit_status += status
		if status:
			color = colors.BAD
			msg = 'FAIL'
		else:
			color = colors.GOOD
			msg = 'PASS'
		print('| %s%-*s%s | %s%s%s' %
			(color, width, ver, colors.NORMAL, color, msg, colors.NORMAL))
	exit(exit_status)


if __name__ == '__main__':
	try:
		main(sys.argv[1:])
	except KeyboardInterrupt:
		print('interrupted ...', file=sys.stderr)
		exit(1)
