# Copyright: 2005-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Author(s): Brian Harring (ferringb@gentoo.org)

__all__ = ["Mapping", "MutableMapping", "UserDict", "ProtectedDict",
	"LazyLoad", "slot_dict_class"]

import sys
import weakref

class Mapping(object):
	"""
	In python-3.0, the UserDict.DictMixin class has been replaced by
	Mapping and MutableMapping from the collections module, but 2to3
	doesn't currently account for this change:

	    https://bugs.python.org/issue2876

	As a workaround for the above issue, use this class as a substitute
	for UserDict.DictMixin so that code converted via 2to3 will run.
	"""

	__slots__ = ()

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

	def keys(self):
		return list(self.__iter__())

	def __contains__(self, key):
		try:
			value = self[key]
		except KeyError:
			return False
		return True

	def iteritems(self):
		for k in self:
			yield (k, self[k])

	def iterkeys(self):
		return self.__iter__()

	def itervalues(self):
		for _, v in self.items():
			yield v

	def values(self):
		return [v for _, v in self.iteritems()]

	def items(self):
		return list(self.iteritems())

	def get(self, key, default=None):
		try:
			return self[key]
		except KeyError:
			return default

	def __repr__(self):
		return repr(dict(self.items()))

	def __len__(self):
		return len(list(self))

	if sys.hexversion >= 0x3000000:
		items = iteritems
		keys = __iter__
		values = itervalues

class MutableMapping(Mapping):
	"""
	A mutable vesion of the Mapping class.
	"""

	__slots__ = ()

	def clear(self):
		for key in list(self):
			del self[key]

	def setdefault(self, key, default=None):
		try:
			return self[key]
		except KeyError:
			self[key] = default
		return default

	def pop(self, key, *args):
		if len(args) > 1:
			raise TypeError("pop expected at most 2 arguments, got " + \
				repr(1 + len(args)))
		try:
			value = self[key]
		except KeyError:
			if args:
				return args[0]
			raise
		del self[key]
		return value

	def popitem(self):
		try:
			k, v = next(iter(self.items()))
		except StopIteration:
			raise KeyError('container is empty')
		del self[k]
		return (k, v)

	def update(self, *args, **kwargs):
		if len(args) > 1:
			raise TypeError(
				"expected at most 1 positional argument, got " + \
				repr(len(args)))
		other = None
		if args:
			other = args[0]
		if other is None:
			pass
		elif hasattr(other, 'iteritems'):
			# Use getattr to avoid interference from 2to3.
			for k, v in getattr(other, 'iteritems')():
				self[k] = v
		elif hasattr(other, 'items'):
			# Use getattr to avoid interference from 2to3.
			for k, v in getattr(other, 'items')():
				self[k] = v
		elif hasattr(other, 'keys'):
			for k in other.keys():
				self[k] = other[k]
		else:
			for k, v in other:
				self[k] = v
		if kwargs:
			self.update(kwargs)

class UserDict(MutableMapping):
	"""
	Use this class as a substitute for UserDict.UserDict so that
	code converted via 2to3 will run:

	     https://bugs.python.org/issue2876
	"""

	__slots__ = ('data',)

	def __init__(self, *args, **kwargs):

		self.data = {}

		if len(args) > 1:
			raise TypeError(
				"expected at most 1 positional argument, got " + \
				repr(len(args)))

		if args:
			self.update(args[0])

		if kwargs:
			self.update(kwargs)

	def __repr__(self):
		return repr(self.data)

	def __contains__(self, key):
		return key in self.data

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

	def __len__(self):
		return len(self.data)

	def __getitem__(self, key):
		return self.data[key]

	def __setitem__(self, key, item):
		self.data[key] = item

	def __delitem__(self, key):
		del self.data[key]

	def clear(self):
		self.data.clear()

	if sys.hexversion >= 0x3000000:
		keys = __iter__

class OrderedDict(UserDict):

	__slots__ = ('_order',)

	def __init__(self, *args, **kwargs):
		self._order = []
		UserDict.__init__(self, *args, **kwargs)

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

	def __setitem__(self, key, item):
		new_key = key not in self
		UserDict.__setitem__(self, key, item)
		if new_key:
			self._order.append(key)

	def __delitem__(self, key):
		UserDict.__delitem__(self, key)
		self._order.remove(key)

	def clear(self):
		UserDict.clear(self)
		del self._order[:]

	if sys.hexversion >= 0x3000000:
		keys = __iter__

class ProtectedDict(MutableMapping):
	"""
	given an initial dict, this wraps that dict storing changes in a secondary dict, protecting
	the underlying dict from changes
	"""
	__slots__=("orig","new","blacklist")

	def __init__(self, orig):
		self.orig = orig
		self.new = {}
		self.blacklist = {}


	def __setitem__(self, key, val):
		self.new[key] = val
		if key in self.blacklist:
			del self.blacklist[key]


	def __getitem__(self, key):
		if key in self.new:
			return self.new[key]
		if key in self.blacklist:
			raise KeyError(key)
		return self.orig[key]


	def __delitem__(self, key):
		if key in self.new:
			del self.new[key]
		elif key in self.orig:
			if key not in self.blacklist:
				self.blacklist[key] = True
				return
		raise KeyError(key)
			

	def __iter__(self):
		for k in self.new:
			yield k
		for k in self.orig:
			if k not in self.blacklist and k not in self.new:
				yield k

	def __contains__(self, key):
		return key in self.new or (key not in self.blacklist and key in self.orig)

	if sys.hexversion >= 0x3000000:
		keys = __iter__

class LazyLoad(Mapping):
	"""
	Lazy loading of values for a dict
	"""
	__slots__=("pull", "d")

	def __init__(self, pull_items_func, initial_items=[]):
		self.d = {}
		for k, v in initial_items:
			self.d[k] = v
		self.pull = pull_items_func

	def __getitem__(self, key):
		if key in self.d:
			return self.d[key]
		elif self.pull != None:
			self.d.update(self.pull())
			self.pull = None
		return self.d[key]

	def __iter__(self):
		if self.pull is not None:
			self.d.update(self.pull())
			self.pull = None
		return iter(self.d)

	def __contains__(self, key):
		if key in self.d:
			return True
		elif self.pull != None:
			self.d.update(self.pull())
			self.pull = None
		return key in self.d

	if sys.hexversion >= 0x3000000:
		keys = __iter__

_slot_dict_classes = weakref.WeakValueDictionary()

def slot_dict_class(keys, prefix="_val_"):
	"""
	Generates mapping classes that behave similar to a dict but store values
	as object attributes that are allocated via __slots__. Instances of these
	objects have a smaller memory footprint than a normal dict object.

	@param keys: Fixed set of allowed keys
	@type keys: Iterable
	@param prefix: a prefix to use when mapping
		attribute names from keys
	@type prefix: String
	@rtype: SlotDict
	@return: A class that constructs SlotDict instances
		having the specified keys.
	"""
	if isinstance(keys, frozenset):
		keys_set = keys
	else:
		keys_set = frozenset(keys)
	v = _slot_dict_classes.get((keys_set, prefix))
	if v is None:

		class SlotDict(object):

			allowed_keys = keys_set
			_prefix = prefix
			__slots__ = ("__weakref__",) + \
				tuple(prefix + k for k in allowed_keys)

			def __init__(self, *args, **kwargs):

				if len(args) > 1:
					raise TypeError(
						"expected at most 1 positional argument, got " + \
						repr(len(args)))

				if args:
					self.update(args[0])

				if kwargs:
					self.update(kwargs)

			def __iter__(self):
				for k, v in self.iteritems():
					yield k

			def __len__(self):
				l = 0
				for i in self.iteritems():
					l += 1
				return l

			def keys(self):
				return list(self)

			def iteritems(self):
				prefix = self._prefix
				for k in self.allowed_keys:
					try:
						yield (k, getattr(self, prefix + k))
					except AttributeError:
						pass

			def items(self):
				return list(self.iteritems())

			def itervalues(self):
				for k, v in self.iteritems():
					yield v

			def values(self):
				return list(self.itervalues())

			def __delitem__(self, k):
				try:
					delattr(self, self._prefix + k)
				except AttributeError:
					raise KeyError(k)

			def __setitem__(self, k, v):
				setattr(self, self._prefix + k, v)

			def setdefault(self, key, default=None):
				try:
					return self[key]
				except KeyError:
					self[key] = default
				return default

			def update(self, *args, **kwargs):
				if len(args) > 1:
					raise TypeError(
						"expected at most 1 positional argument, got " + \
						repr(len(args)))
				other = None
				if args:
					other = args[0]
				if other is None:
					pass
				elif hasattr(other, 'iteritems'):
					# Use getattr to avoid interference from 2to3.
					for k, v in getattr(other, 'iteritems')():
						self[k] = v
				elif hasattr(other, 'items'):
					# Use getattr to avoid interference from 2to3.
					for k, v in getattr(other, 'items')():
						self[k] = v
				elif hasattr(other, 'keys'):
					for k in other.keys():
						self[k] = other[k]
				else:
					for k, v in other:
						self[k] = v
				if kwargs:
					self.update(kwargs)

			def __getitem__(self, k):
				try:
					return getattr(self, self._prefix + k)
				except AttributeError:
					raise KeyError(k)

			def get(self, key, default=None):
				try:
					return self[key]
				except KeyError:
					return default

			def __contains__(self, k):
				return hasattr(self, self._prefix + k)

			def pop(self, key, *args):
				if len(args) > 1:
					raise TypeError(
						"pop expected at most 2 arguments, got " + \
						repr(1 + len(args)))
				try:
					value = self[key]
				except KeyError:
					if args:
						return args[0]
					raise
				del self[key]
				return value

			def popitem(self):
				try:
					k, v = self.iteritems().next()
				except StopIteration:
					raise KeyError('container is empty')
				del self[k]
				return (k, v)

			def copy(self):
				c = self.__class__()
				c.update(self)
				return c

			def clear(self):
				for k in self.allowed_keys:
					try:
						delattr(self, self._prefix + k)
					except AttributeError:
						pass

			def __str__(self):
				return str(dict(self.iteritems()))

			def __repr__(self):
				return repr(dict(self.iteritems()))

			if sys.hexversion >= 0x3000000:
				items = iteritems
				keys = __iter__
				values = itervalues

		v = SlotDict
		_slot_dict_classes[v.allowed_keys] = v
	return v
