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

from __future__ import unicode_literals

import sys
import warnings

import portage
from portage import os
from _emerge.Package import Package
from _emerge.PackageVirtualDbapi import PackageVirtualDbapi
from portage.const import VDB_PATH
from portage.dbapi.vartree import vartree
from portage.dep._slot_operator import find_built_slot_operator_atoms
from portage.eapi import _get_eapi_attrs
from portage.exception import InvalidData, InvalidDependString
from portage.update import grab_updates, parse_updates, update_dbentries
from portage.versions import _pkg_str

if sys.hexversion >= 0x3000000:
	long = int
	_unicode = str
else:
	_unicode = unicode

class FakeVardbapi(PackageVirtualDbapi):
	"""
	Implements the vardbapi.getpath() method which is used in error handling
	code for the Package class and vartree.get_provide().
	"""
	def getpath(self, cpv, filename=None):
		path = os.path.join(self.settings['EROOT'], VDB_PATH, cpv)
		if filename is not None:
			path =os.path.join(path, filename)
		return path

class _DynamicDepsNotApplicable(Exception):
	pass

class FakeVartree(vartree):
	"""This is implements an in-memory copy of a vartree instance that provides
	all the interfaces required for use by the depgraph.  The vardb is locked
	during the constructor call just long enough to read a copy of the
	installed package information.  This allows the depgraph to do it's
	dependency calculations without holding a lock on the vardb.  It also
	allows things like vardb global updates to be done in memory so that the
	user doesn't necessarily need write access to the vardb in cases where
	global updates are necessary (updates are performed when necessary if there
	is not a matching ebuild in the tree). Instances of this class are not
	populated until the sync() method is called."""
	def __init__(self, root_config, pkg_cache=None, pkg_root_config=None,
		dynamic_deps=True, ignore_built_slot_operator_deps=False):
		self._root_config = root_config
		self._dynamic_deps = dynamic_deps
		self._ignore_built_slot_operator_deps = ignore_built_slot_operator_deps
		if pkg_root_config is None:
			pkg_root_config = self._root_config
		self._pkg_root_config = pkg_root_config
		if pkg_cache is None:
			pkg_cache = {}
		real_vartree = root_config.trees["vartree"]
		self._real_vardb = real_vartree.dbapi
		portdb = root_config.trees["porttree"].dbapi
		self.settings = real_vartree.settings
		mykeys = list(real_vartree.dbapi._aux_cache_keys)
		if "_mtime_" not in mykeys:
			mykeys.append("_mtime_")
		self._db_keys = mykeys
		self._pkg_cache = pkg_cache
		self.dbapi = FakeVardbapi(real_vartree.settings)
		self.dbapi._aux_cache_keys = set(self._db_keys)

		# Initialize variables needed for lazy cache pulls of the live ebuild
		# metadata.  This ensures that the vardb lock is released ASAP, without
		# being delayed in case cache generation is triggered.
		self._aux_get = self.dbapi.aux_get
		self._match = self.dbapi.match
		if dynamic_deps:
			self.dbapi.aux_get = self._aux_get_wrapper
			self.dbapi.match = self._match_wrapper
		self._aux_get_history = set()
		self._portdb_keys = Package._dep_keys + ("EAPI", "KEYWORDS")
		self._portdb = portdb
		self._global_updates = None

	@property
	def root(self):
		warnings.warn("The root attribute of "
			"_emerge.FakeVartree.FakeVartree"
			" is deprecated. Use "
			"settings['ROOT'] instead.",
			DeprecationWarning, stacklevel=3)
		return self.settings['ROOT']

	def _match_wrapper(self, cpv, use_cache=1):
		"""
		Make sure the metadata in Package instances gets updated for any
		cpv that is returned from a match() call, since the metadata can
		be accessed directly from the Package instance instead of via
		aux_get().
		"""
		matches = self._match(cpv, use_cache=use_cache)
		for cpv in matches:
			if cpv in self._aux_get_history:
				continue
			self._aux_get_wrapper(cpv, [])
		return matches

	def _aux_get_wrapper(self, cpv, wants, myrepo=None):
		if cpv in self._aux_get_history:
			return self._aux_get(cpv, wants)
		self._aux_get_history.add(cpv)

		# This raises a KeyError to the caller if appropriate.
		pkg = self.dbapi._cpv_map[cpv]

		try:
			live_metadata = dict(zip(self._portdb_keys,
				self._portdb.aux_get(cpv, self._portdb_keys,
				myrepo=pkg.repo)))
		except (KeyError, portage.exception.PortageException):
			live_metadata = None

		self._apply_dynamic_deps(pkg, live_metadata)

		return self._aux_get(cpv, wants)

	def _apply_dynamic_deps(self, pkg, live_metadata):

		try:
			if live_metadata is None:
				raise _DynamicDepsNotApplicable()
			# Use the metadata from the installed instance if the EAPI
			# of either instance is unsupported, since if the installed
			# instance has an unsupported or corrupt EAPI then we don't
			# want to attempt to do complex operations such as execute
			# pkg_config, pkg_prerm or pkg_postrm phases. If both EAPIs
			# are supported then go ahead and use the live_metadata, in
			# order to respect dep updates without revision bump or EAPI
			# bump, as in bug #368725.
			if not (portage.eapi_is_supported(live_metadata["EAPI"]) and \
				portage.eapi_is_supported(pkg.eapi)):
				raise _DynamicDepsNotApplicable()

			# preserve built slot/sub-slot := operator deps
			built_slot_operator_atoms = None
			if not self._ignore_built_slot_operator_deps and \
				_get_eapi_attrs(pkg.eapi).slot_operator:
				try:
					built_slot_operator_atoms = \
						find_built_slot_operator_atoms(pkg)
				except InvalidDependString:
					pass

			if built_slot_operator_atoms:
				live_eapi_attrs = _get_eapi_attrs(live_metadata["EAPI"])
				if not live_eapi_attrs.slot_operator:
					raise _DynamicDepsNotApplicable()
				for k, v in built_slot_operator_atoms.items():
					live_metadata[k] += (" " +
						" ".join(_unicode(atom) for atom in v))

			self.dbapi.aux_update(pkg.cpv, live_metadata)
		except _DynamicDepsNotApplicable:
			if self._global_updates is None:
				self._global_updates = \
					grab_global_updates(self._portdb)

			# Bypass _aux_get_wrapper, since calling that
			# here would trigger infinite recursion.
			aux_keys = Package._dep_keys + self.dbapi._pkg_str_aux_keys
			aux_dict = dict(zip(aux_keys, self._aux_get(pkg.cpv, aux_keys)))
			perform_global_updates(
				pkg.cpv, aux_dict, self.dbapi, self._global_updates)

	def dynamic_deps_preload(self, pkg, metadata):
		if metadata is not None:
			metadata = dict((k, metadata.get(k, ''))
				for k in self._portdb_keys)
		self._apply_dynamic_deps(pkg, metadata)
		self._aux_get_history.add(pkg.cpv)

	def cpv_discard(self, pkg):
		"""
		Discard a package from the fake vardb if it exists.
		"""
		old_pkg = self.dbapi.get(pkg)
		if old_pkg is not None:
			self.dbapi.cpv_remove(old_pkg)
			self._pkg_cache.pop(old_pkg, None)
			self._aux_get_history.discard(old_pkg.cpv)

	def sync(self, acquire_lock=1):
		"""
		Call this method to synchronize state with the real vardb
		after one or more packages may have been installed or
		uninstalled.
		"""
		locked = False
		try:
			if acquire_lock and os.access(self._real_vardb._dbroot, os.W_OK):
				self._real_vardb.lock()
				locked = True
			self._sync()
		finally:
			if locked:
				self._real_vardb.unlock()

		# Populate the old-style virtuals using the cached values.
		# Skip the aux_get wrapper here, to avoid unwanted
		# cache generation.
		try:
			self.dbapi.aux_get = self._aux_get
			self.settings._populate_treeVirtuals_if_needed(self)
		finally:
			if self._dynamic_deps:
				self.dbapi.aux_get = self._aux_get_wrapper

	def _sync(self):

		real_vardb = self._root_config.trees["vartree"].dbapi
		current_cpv_set = frozenset(real_vardb.cpv_all())
		pkg_vardb = self.dbapi

		# Remove any packages that have been uninstalled.
		for pkg in list(pkg_vardb):
			if pkg.cpv not in current_cpv_set:
				self.cpv_discard(pkg)

		# Validate counters and timestamps.
		slot_counters = {}
		root_config = self._pkg_root_config
		validation_keys = ["COUNTER", "_mtime_"]
		for cpv in current_cpv_set:

			pkg_hash_key = Package._gen_hash_key(cpv=cpv,
				installed=True, root_config=root_config,
				type_name="installed")
			pkg = pkg_vardb.get(pkg_hash_key)
			if pkg is not None:
				counter, mtime = real_vardb.aux_get(cpv, validation_keys)
				try:
					counter = long(counter)
				except ValueError:
					counter = 0

				if counter != pkg.counter or \
					mtime != pkg.mtime:
					self.cpv_discard(pkg)
					pkg = None

			if pkg is None:
				pkg = self._pkg(cpv)

			other_counter = slot_counters.get(pkg.slot_atom)
			if other_counter is not None:
				if other_counter > pkg.counter:
					continue

			slot_counters[pkg.slot_atom] = pkg.counter
			pkg_vardb.cpv_inject(pkg)

		real_vardb.flush_cache()

	def _pkg(self, cpv):
		"""
		The RootConfig instance that will become the Package.root_config
		attribute can be overridden by the FakeVartree pkg_root_config
		constructory argument, since we want to be consistent with the
		depgraph._pkg() method which uses a specially optimized
		RootConfig that has a FakeVartree instead of a real vartree.
		"""
		pkg = Package(cpv=cpv, built=True, installed=True,
			metadata=zip(self._db_keys,
			self._real_vardb.aux_get(cpv, self._db_keys)),
			root_config=self._pkg_root_config,
			type_name="installed")

		self._pkg_cache[pkg] = pkg
		return pkg

def grab_global_updates(portdb):
	retupdates = {}

	for repo_name in portdb.getRepositories():
		repo = portdb.getRepositoryPath(repo_name)
		updpath = os.path.join(repo, "profiles", "updates")
		if not os.path.isdir(updpath):
			continue

		try:
			rawupdates = grab_updates(updpath)
		except portage.exception.DirectoryNotFound:
			rawupdates = []
		upd_commands = []
		for mykey, mystat, mycontent in rawupdates:
			commands, errors = parse_updates(mycontent)
			upd_commands.extend(commands)
		retupdates[repo_name] = upd_commands

	master_repo = portdb.getRepositoryName(portdb.porttree_root)
	if master_repo in retupdates:
		retupdates['DEFAULT'] = retupdates[master_repo]

	return retupdates

def perform_global_updates(mycpv, aux_dict, mydb, myupdates):
	try:
		pkg = _pkg_str(mycpv, metadata=aux_dict, settings=mydb.settings)
	except InvalidData:
		return
	aux_dict = dict((k, aux_dict[k]) for k in Package._dep_keys)
	try:
		mycommands = myupdates[pkg.repo]
	except KeyError:
		try:
			mycommands = myupdates['DEFAULT']
		except KeyError:
			return

	if not mycommands:
		return

	updates = update_dbentries(mycommands, aux_dict, parent=pkg)
	if updates:
		mydb.aux_update(mycpv, updates)
