# Copyright 2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

import subprocess
import sys
import textwrap

import portage
from portage import os
from portage import _unicode_decode
from portage.const import (BASH_BINARY, PORTAGE_BIN_PATH,
	PORTAGE_PYM_PATH, USER_CONFIG_PATH)
from portage.tests import TestCase
from portage.tests.resolver.ResolverPlayground import ResolverPlayground
from portage.util import ensure_dirs

class PortdbCacheTestCase(TestCase):

	def testPortdbCache(self):
		debug = False

		ebuilds = {
			"dev-libs/A-1": {},
			"dev-libs/A-2": {},
			"sys-apps/B-1": {},
			"sys-apps/B-2": {},
		}

		playground = ResolverPlayground(ebuilds=ebuilds, debug=debug)
		settings = playground.settings
		eprefix = settings["EPREFIX"]
		portdir = settings["PORTDIR"]
		user_config_dir = os.path.join(eprefix, USER_CONFIG_PATH)
		metadata_dir = os.path.join(portdir, "metadata")
		md5_cache_dir = os.path.join(metadata_dir, "md5-cache")
		pms_cache_dir = os.path.join(metadata_dir, "cache")
		layout_conf_path = os.path.join(metadata_dir, "layout.conf")

		portage_python = portage._python_interpreter
		egencache_cmd = (portage_python, "-Wd",
			os.path.join(PORTAGE_BIN_PATH, "egencache"))
		python_cmd = (portage_python, "-Wd", "-c")

		test_commands = (
			(lambda: not os.path.exists(pms_cache_dir),),
			(lambda: not os.path.exists(md5_cache_dir),),
			python_cmd + (textwrap.dedent("""
				import os, sys, portage
				if portage.portdb.porttree_root in portage.portdb._pregen_auxdb:
					sys.exit(1)
			"""),),

			egencache_cmd + ("--update",),
			(lambda: not os.path.exists(pms_cache_dir),),
			(lambda: os.path.exists(md5_cache_dir),),
			python_cmd + (textwrap.dedent("""
				import os, sys, portage
				if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
					sys.exit(1)
			"""),),
			python_cmd + (textwrap.dedent("""
				import os, sys, portage
				from portage.cache.flat_hash import md5_database
				if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database):
					sys.exit(1)
			"""),),

			(BASH_BINARY, "-c", "echo %s > %s" %
				tuple(map(portage._shell_quote,
				("cache-formats = md5-dict pms", layout_conf_path,)))),
			egencache_cmd + ("--update",),
			(lambda: os.path.exists(md5_cache_dir),),
			python_cmd + (textwrap.dedent("""
				import os, sys, portage
				if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
					sys.exit(1)
			"""),),
			python_cmd + (textwrap.dedent("""
				import os, sys, portage
				from portage.cache.flat_hash import md5_database
				if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database):
					sys.exit(1)
			"""),),

			# Don't use python -Wd, since the pms format triggers deprecation warnings
			# in portdbapi._create_pregen_cache().
			(BASH_BINARY, "-c", "echo %s > %s" %
				tuple(map(portage._shell_quote,
				("cache-formats = pms md5-dict", layout_conf_path,)))),
			(portage_python, "-Wi", "-c") + (textwrap.dedent("""
				import os, sys, portage
				if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
					sys.exit(1)
			"""),),
			(portage_python, "-Wi", "-c") + (textwrap.dedent("""
				import os, sys, portage
				from portage.cache.metadata import database as pms_database
				if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], pms_database):
					sys.exit(1)
			"""),),

			# Test auto-detection and preference for md5-cache when both
			# cache formats are available but layout.conf is absent.
			(BASH_BINARY, "-c", "rm %s" % portage._shell_quote(layout_conf_path)),
			python_cmd + (textwrap.dedent("""
				import os, sys, portage
				if portage.portdb.porttree_root not in portage.portdb._pregen_auxdb:
					sys.exit(1)
			"""),),
			python_cmd + (textwrap.dedent("""
				import os, sys, portage
				from portage.cache.flat_hash import md5_database
				if not isinstance(portage.portdb._pregen_auxdb[portage.portdb.porttree_root], md5_database):
					sys.exit(1)
			"""),),
		)

		pythonpath =  os.environ.get("PYTHONPATH")
		if pythonpath is not None and not pythonpath.strip():
			pythonpath = None
		if pythonpath is not None and \
			pythonpath.split(":")[0] == PORTAGE_PYM_PATH:
			pass
		else:
			if pythonpath is None:
				pythonpath = ""
			else:
				pythonpath = ":" + pythonpath
			pythonpath = PORTAGE_PYM_PATH + pythonpath

		env = {
			"PATH" : os.environ.get("PATH", ""),
			"PORTAGE_OVERRIDE_EPREFIX" : eprefix,
			"PORTAGE_PYTHON" : portage_python,
			"PYTHONPATH" : pythonpath,
		}

		if "__PORTAGE_TEST_HARDLINK_LOCKS" in os.environ:
			env["__PORTAGE_TEST_HARDLINK_LOCKS"] = \
				os.environ["__PORTAGE_TEST_HARDLINK_LOCKS"]

		dirs = [user_config_dir]

		try:
			for d in dirs:
				ensure_dirs(d)

			if debug:
				# The subprocess inherits both stdout and stderr, for
				# debugging purposes.
				stdout = None
			else:
				# The subprocess inherits stderr so that any warnings
				# triggered by python -Wd will be visible.
				stdout = subprocess.PIPE

			for i, args in enumerate(test_commands):

				if hasattr(args[0], '__call__'):
					self.assertTrue(args[0](),
						"callable at index %s failed" % (i,))
					continue

				proc = subprocess.Popen(args,
					env=env, stdout=stdout)

				if debug:
					proc.wait()
				else:
					output = proc.stdout.readlines()
					proc.wait()
					proc.stdout.close()
					if proc.returncode != os.EX_OK:
						for line in output:
							sys.stderr.write(_unicode_decode(line))

				self.assertEqual(os.EX_OK, proc.returncode,
					"command %d failed with args %s" % (i, args,))
		finally:
			playground.cleanup()
