import logging

from .namedmatrix import NamedMatrix, PersistentNamedMatrix

###

L = logging.getLogger(__name__)

###


class SessionMatrix(NamedMatrix):
	ConfigDefaults = {
		'primary_name': 'id'
	}

	'''
		Matrix, specific for `SessionAnalyzer`.

	'''

	def __init__(self, app, dtype='float_', id=None, config=None):
		if not isinstance(dtype, str):
			dtype = dtype[:]
		super().__init__(app, dtype=dtype, id=id, config=config)
		self.PrimaryName = self.Config['primary_name']


	def store(self, row_name: str, event):
		'''
			Store the event in the matrix.
			The event must prepared so that it matches a data type of the cell (dtype)
		'''
		row_index = self.get_row_index(row_name)
		if row_index is None:
			return False
		self.Array[row_index] = event


	def store_event(self, row_index: int, event, keys=None):
		if keys is None:
			keys = event.keys()

		names = self.Array.dtype.names
		if names is None:
			L.warning("The matrix does not have correct column-like dtype")
			raise

		for key in keys:
			if key in names:
				self.Array[row_index][key] = event[key]


	def decode_row(self, row_index: int, keys=None):

		if keys is None:
			keys = list(self.Array.dtype.names)

		if keys is None:
			L.warning("The matrix does not have correct column-like dtype")
			raise

		event = dict(zip(keys, self.Array[row_index][keys]))
		event[self.PrimaryName] = self.get_row_name(row_index)

		return event



class PersistentSessionMatrix(PersistentNamedMatrix):
	ConfigDefaults = {
		'primary_name': 'id'
	}

	def __init__(self, app, dtype='float_', id=None, config=None):
		if not isinstance(dtype, str):
			dtype = dtype[:]
		super().__init__(app, dtype=dtype, id=id, config=config)
		self.PrimaryName = self.Config['primary_name']


	def store(self, row_name: str, event):
		'''
			Store the event in the matrix.
			The event must prepared so that it matches a data type of the cell (dtype)
		'''
		row_index = self.get_row_index(row_name)
		if row_index is None:
			return False
		self.Array[row_index] = event


	def store_event(self, row_index: int, event, keys=None):
		if keys is None:
			keys = event.keys()

		names = self.Array.dtype.names
		if names is None:
			L.warning("The matrix does not have correct column-like dtype")
			raise

		for key in keys:
			if key in names:
				self.Array[row_index][key] = event[key]


	def decode_row(self, row_index: int, keys=None):

		if keys is None:
			keys = list(self.Array.dtype.names)

		if keys is None:
			L.warning("The matrix does not have correct column-like dtype")
			raise

		event = dict(zip(keys, self.Array[row_index][keys]))
		event[self.PrimaryName] = self.get_row_name(row_index)

		return event
