import requests
from abc import ABC, abstractmethod
from time import sleep
#I learned how to get dad jokes every 10 seconds from the following pages:
# https://icanhazdadjoke.com/api
# http://docs.python-requests.org/en/master/
# https://stackoverflow.com/questions/3393612/run-certain-code-every-n-seconds

class JokePublisher(ABC):

	@abstractmethod
	def Attach(self):
		pass

	@abstractmethod
	def Detach(self):
		pass

	@abstractmethod
	def Notify(self):
		pass

class JokeTeller(ABC):

	@abstractmethod
	def Update(self):
		pass

class ConcreteJokePublisher(JokePublisher):

	def __init__(self):
		self._observers = set()
		self._newestJoke = ''

	@property
	def newestJoke(self):
		return self._newestJoke

	@newestJoke.setter
	def newestJoke(self, newestJoke):
		self._newestJoke = newestJoke
		self.Notify()

	def Attach(self, newObserver):
		self._observers.add(newObserver)

	def Detach(self, oldObserver):
		self._observers.remove(oldObserver)

	def Notify(self):
		for observer in self._observers:
			observer.Update(self.newestJoke)

class ConcreteJokeTeller(JokeTeller):

	def __init__(self):
		self._newestJoke = ''

	@property
	def newestJoke(self):
		return self._newestJoke

	@newestJoke.setter
	def newestJoke(self, newestJoke):
		self._newestJoke = newestJoke

	def Update(self, newestJoke):
		self.newestJoke = newestJoke
		print(self.newestJoke)

def main():

	the_subject = ConcreteJokePublisher()
	the_observer = ConcreteJokeTeller()
	the_subject.Attach(the_observer)
	while True:
		joke = requests.get('https://icanhazdadjoke.com', headers={"Accept":"text/plain"})
		the_subject.newestJoke = joke.text
		sleep(8)
		more_jokes = input('Would you like to hear another one? Y/N ')
		if more_jokes == 'N':
			the_subject.Detach(the_observer)
			break


if __name__ == "__main__": main()