import threading
import requests, json

from core.models import *
#from openstack.manager import OpenStackManager
from planetstack.config import Config
from observer.deleters import deleters

import os
import base64
from fofum import Fofum
import json

# decorator that marks dispatachable event methods	
def event(func):
	setattr(func, 'event', func.__name__)
	return func		 

class EventHandler:
	# This code is currently not in use.
	def __init__(self):
		pass #self.manager = OpenStackManager()

	@staticmethod
	def get_events():
		events = []
		for name in dir(EventHandler):
			attribute = getattr(EventHandler, name)
			if hasattr(attribute, 'event'):
				events.append(getattr(attribute, 'event'))
		return events

	def dispatch(self, event, *args, **kwds):
		if hasattr(self, event):
			return getattr(self, event)(*args, **kwds)
			
		
class EventSender:
	def __init__(self,user=None,clientid=None):
		try:
			clid = Config().feefie_client_id
			user = Config().feefie_client_user
		except:
			clid = 'planetstack_core_team'
			user = 'pl'

		self.fofum = Fofum(user=user)
		self.fofum.make(clid)

	def fire(self,**args):
		self.fofum.fire(json.dumps(args))

class EventListener:
	def __init__(self,wake_up=None):
		self.handler = EventHandler()
		self.wake_up = wake_up

	def handle_event(self, payload):
		payload_dict = json.loads(payload)

		try:
			deletion = payload_dict['deletion_flag']
			if (deletion):
				model = payload_dict['model']
				pk = payload_dict['pk']

				for deleter in deleters[model]:
					deleter(pk)
		except:
			deletion = False

		if (not deletion and self.wake_up):
			self.wake_up()
		

	def run(self):
		# This is our unique client id, to be used when firing and receiving events
		# It needs to be generated once and placed in the config file

		try:
			clid = Config().feefie_client_id
			user = Config().feefie_client_user
		except:
			clid = 'planetstack_core_team'
			user = 'pl'

		f = Fofum(user=user)
		
		listener_thread = threading.Thread(target=f.listen_for_event,args=(clid,self.handle_event))
		listener_thread.start()
