from caches import BaseCache, navigator_db, get_property, set_property, clear_property
from modules import menu_lists as default_menus
from modules.kodi_utils import logger

main_menus = default_menus.main_menus
GET_LIST = 'SELECT list_contents FROM navigator WHERE list_name = ? AND list_type = ?'
SET_LIST = 'INSERT OR REPLACE INTO navigator VALUES (?, ?, ?)'
DELETE_LIST = 'DELETE FROM navigator WHERE list_name = ? and list_type = ?'
GET_FOLDERS = 'SELECT list_name, list_contents FROM navigator WHERE list_type = ?'
GET_FOLDER_CONTENTS = 'SELECT list_contents FROM navigator WHERE list_name = ? AND list_type = ?'
prop_dict = {'default': 'alkoflix_%s_default', 'edited': 'alkoflix_%s_edited', 'shortcut_folder': 'alkoflix_%s_shortcut_folder', 'shortcut_folder_icon': 'alkoflix_%s_shortcut_folder_icon'}

class NavigatorCache(BaseCache):
	db_file = navigator_db

	def get_main_lists(self, list_name):
		default_contents = self.get_memory_cache(list_name, 'default')
		if not default_contents:
			default_contents = self.get_list(list_name, 'default')
			if default_contents is None:
				self.rebuild_database()
				default_contents = self.get_list(list_name, 'default')
				if default_contents is None and list_name in main_menus:
					default_contents = main_menus[list_name]
					self.set_list(list_name, 'default', default_contents)
				if default_contents is None:
					return [], None
			try: edited_contents = self.get_list(list_name, 'edited')
			except: edited_contents = None
		else:
			edited_contents = self.get_memory_cache(list_name, 'edited')
			if edited_contents is None:
				try: edited_contents = self.get_list(list_name, 'edited')
				except: edited_contents = None
				if edited_contents is not None: self.set_memory_cache(list_name, 'edited', edited_contents)
		return default_contents, edited_contents

	def get_list(self, list_name, list_type):
		contents = None
		try: contents = eval(self.dbcur.execute(GET_LIST, (list_name, list_type)).fetchone()[0])
		except: pass
		return contents

	def set_list(self, list_name, list_type, list_contents):
		self.dbcur.execute(SET_LIST, (list_name, list_type, repr(list_contents)))
		self.set_memory_cache(list_name, list_type, list_contents)

	def delete_list(self, list_name, list_type):
		self.dbcur.execute(DELETE_LIST, (list_name, list_type))
		self.delete_memory_cache(list_name, list_type)
		self.dbcur.execute("""VACUUM""")

	def get_memory_cache(self, list_name, list_type):
		try: return eval(get_property(self._get_list_prop(list_type) % list_name))
		except: return None

	def set_memory_cache(self, list_name, list_type, list_contents):
		set_property(self._get_list_prop(list_type) % list_name, repr(list_contents))

	def delete_memory_cache(self, list_name, list_type):
		clear_property(self._get_list_prop(list_type) % list_name)

	def get_shortcut_folders(self):
		try:
			folders = self.dbcur.execute(GET_FOLDERS, ('shortcut_folder',)).fetchall()
			folders = sorted([(str(i[0]), i[1]) for i in folders], key=lambda s: s[0].lower())
		except: folders = []
		return folders

	def get_shortcut_folder_contents(self, list_name):
		contents = []
		try: contents = eval(self.dbcur.execute(GET_FOLDER_CONTENTS, (list_name, 'shortcut_folder')).fetchone()[0])
		except: pass
		return contents

	def get_shortcut_folder_icon(self, list_name):
		icon = self.get_list(list_name, 'shortcut_folder_icon')
		if icon in ('', 'None', None): return 'myfolder.png'
		return str(icon)

	def set_shortcut_folder_icon(self, list_name, icon):
		icon = str(icon or '').strip()
		if not icon or icon == 'myfolder.png':
			return self.delete_shortcut_folder_icon(list_name)
		self.set_list(list_name, 'shortcut_folder_icon', icon)

	def delete_shortcut_folder_icon(self, list_name):
		try: self.delete_list(list_name, 'shortcut_folder_icon')
		except: pass

	def currently_used_list(self, list_name):
		default_contents, edited_contents = self.get_main_lists(list_name)
		list_items = edited_contents or default_contents
		return list_items

	def rebuild_database(self):
		for list_name, list_contents in main_menus.items(): self.set_list(list_name, 'default', list_contents)

	def clear_menu_cache(self, rebuild_defaults=True):
		# Nettoie le cache navigateur sans supprimer les menus édités ni les dossiers personnalisés.
		# navigator.db contient aussi des données utilisateur; il ne faut donc pas le supprimer.
		stats = {'default_deleted': 0, 'props_cleared': 0, 'defaults_rebuilt': 0, 'edited_kept': 0, 'shortcut_kept': 0, 'shortcut_icon_kept': 0}
		try:
			rows = self.dbcur.execute("""SELECT list_name, list_type FROM navigator""").fetchall()
		except Exception as exc:
			rows = []
			logger('alkoFlix NavigatorCache clear rows failed', str(exc))
		known_rows = set((str(i[0]), str(i[1])) for i in rows)
		for list_name in main_menus:
			known_rows.add((list_name, 'default'))
			known_rows.add((list_name, 'edited'))
		for list_name, list_type in known_rows:
			if list_type in prop_dict:
				try:
					self.delete_memory_cache(list_name, list_type)
					stats['props_cleared'] += 1
				except Exception as exc:
					logger('alkoFlix NavigatorCache clear property failed', '%s/%s | %s' % (list_name, list_type, exc))
		try:
			stats['edited_kept'] = self.dbcur.execute("""SELECT COUNT(*) FROM navigator WHERE list_type = ?""", ('edited',)).fetchone()[0]
		except: pass
		try:
			stats['shortcut_kept'] = self.dbcur.execute("""SELECT COUNT(*) FROM navigator WHERE list_type = ?""", ('shortcut_folder',)).fetchone()[0]
		except: pass
		try:
			stats['shortcut_icon_kept'] = self.dbcur.execute("""SELECT COUNT(*) FROM navigator WHERE list_type = ?""", ('shortcut_folder_icon',)).fetchone()[0]
		except: pass
		try:
			self.dbcur.execute("""DELETE FROM navigator WHERE list_type = ?""", ('default',))
			stats['default_deleted'] = self.dbcur.rowcount if self.dbcur.rowcount not in (None, -1) else 0
		except Exception as exc:
			logger('alkoFlix NavigatorCache delete defaults failed', str(exc))
		if rebuild_defaults:
			for list_name, list_contents in main_menus.items():
				try:
					self.set_list(list_name, 'default', list_contents)
					stats['defaults_rebuilt'] += 1
				except Exception as exc:
					logger('alkoFlix NavigatorCache rebuild default failed', '%s | %s' % (list_name, exc))
		try: self.dbcur.execute("""VACUUM""")
		except: pass
		logger('alkoFlix NavigatorCache cleared', 'defaults_deleted=%s | defaults_rebuilt=%s | props_cleared=%s | edited_kept=%s | shortcut_kept=%s | shortcut_icon_kept=%s' % (stats['default_deleted'], stats['defaults_rebuilt'], stats['props_cleared'], stats['edited_kept'], stats['shortcut_kept'], stats['shortcut_icon_kept']))
		return stats

	def _get_list_prop(self, list_type):
		return prop_dict[list_type]

navigator_cache = NavigatorCache()

