import time
import hashlib
import collections


class Session(collections.MutableMapping):

	"""Session dict-like object."""

	def __init__(self, storage, id, new, max_age=None):
		self._id = id
		self._changed = False
		self._mapping = {}
		self._new = new
		self.MaxAge = max_age
		self.Storage = storage

		self._created = int(time.time())


	def __hash__(self):
		return hash((self.__class__, self._id))


	def __repr__(self):
		return '<{} [{}, new:{}, changed:{}, created:{} expired:{}] {!r}>'.format(
			self.__class__.__name__,
			hashlib.sha224(self._id.encode('utf-8')).hexdigest() if self._id is not None else "-",
			self._new, self._changed, self._created, self.is_expired(), self._mapping
		)


	def is_expired(self):
		expiration = self._created + self.MaxAge
		return time.time() >= expiration

	def reset(self):
		self._new = False
		self._change = False


	@property
	def Id(self):
		return self._id

	def set_id(self, id):
		if self._id is not None or not self._new:
			raise RuntimeError("Session id is already set!")
		self._id = id


	@property
	def Created(self):
		return self._created


	def is_new(self):
		return self._new

	def mark_changed(self):
		self._changed = True



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

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

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

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

	def __setitem__(self, key, value):
		self._mapping[key] = value
		self._changed = True

	def __delitem__(self, key):
		del self._mapping[key]
		self._changed = True
