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

import bisect
import collections
import sys

class DbapiProvidesIndex(object):
	"""
	The DbapiProvidesIndex class is used to wrap existing dbapi
	interfaces, index packages by the sonames that they provide, and
	implement the dbapi.match method for SonameAtom instances. Since
	this class acts as a wrapper, it can be used conditionally, so that
	soname indexing overhead is avoided when soname dependency
	resolution is disabled.

	Since it's possible for soname atom match results to consist of
	packages with multiple categories or names, it is essential that
	Package.__lt__ behave meaningfully when Package.cp is dissimilar,
	so that match results will be correctly ordered by version for each
	value of Package.cp.
	"""

	_copy_attrs = ('aux_get', 'aux_update', 'categories', 'cpv_all',
		'cpv_exists', 'cp_all', 'cp_list', 'getfetchsizes',
		'settings', '_aux_cache_keys', '_clear_cache',
		'_cpv_sort_ascending', '_iuse_implicit_cnstr', '_pkg_str',
		'_pkg_str_aux_keys')

	def __init__(self, db):
		self._db = db
		for k in self._copy_attrs:
			try:
				setattr(self, k, getattr(db, k))
			except AttributeError:
				pass
		self._provides_index = collections.defaultdict(list)

	def match(self, atom, use_cache=DeprecationWarning):
		if atom.soname:
			result = self._match_soname(atom)
		else:
			result = self._db.match(atom)
		return result

	def _match_soname(self, atom):
		result = self._provides_index.get(atom)
		if result is None:
			result = []
		else:
			result = [pkg.cpv for pkg in result]
		return result

	def _provides_inject(self, pkg):
		index = self._provides_index
		for atom in pkg.provides:
			# Use bisect.insort for ordered match results.
			bisect.insort(index[atom], pkg)

class PackageDbapiProvidesIndex(DbapiProvidesIndex):
	"""
	This class extends DbapiProvidesIndex in order to make it suitable
	for wrapping a PackageVirtualDbapi instance.
	"""

	_copy_attrs = DbapiProvidesIndex._copy_attrs + (
		"clear", "get", "_cpv_map")

	def clear(self):
		self._db.clear()
		self._provides_index.clear()

	def __bool__(self):
		return bool(self._db)

	if sys.hexversion < 0x3000000:
		__nonzero__ = __bool__

	def __iter__(self):
		return iter(self._db)

	def __contains__(self, item):
		return item in self._db

	def match_pkgs(self, atom):
		return [self._db._cpv_map[cpv] for cpv in self.match(atom)]

	def cpv_inject(self, pkg):
		self._db.cpv_inject(pkg)
		self._provides_inject(pkg)

	def cpv_remove(self, pkg):
		self._db.cpv_remove(pkg)
		index = self._provides_index
		for atom in pkg.provides:
			items = index[atom]
			try:
				items.remove(pkg)
			except ValueError:
				pass
			if not items:
				del index[atom]
