from cppy.cp_util import *

#################################################
# The event management
#################################################
class EventManager:
    def __init__(self):
        self._subscriptions = {}

    def subscribe(self, event_type, handler):
        self._subscriptions.setdefault(event_type, []).append(handler)

    def publish(self, event):
        event_type = event[0]        
        for h in self._subscriptions.get(event_type, []):  
            h(event)

#################################################
# The application entities
#################################################
class DataStorage:
    """ Models the contents of the file """
    def __init__(self, event_manager):
        self._event_manager = event_manager
        self._event_manager.subscribe('load', self.load)
        self._event_manager.subscribe('start', self.produce_words)

    def load(self, event):        
        self._data = extract_file_words( event[1] )

    def produce_words(self, event):        
        for w in self._data:
            self._event_manager.publish(('word', w))
        self._event_manager.publish(('eof', None))

class StopWordFilter:
    """ Models the stop word filter """
    def __init__(self, event_manager):
        self._stop_words = []
        self._event_manager = event_manager
        self._event_manager.subscribe('load', self.load)
        self._event_manager.subscribe('word', self.is_stop_word)

    def load(self, event):        
        self._stop_words = get_stopwords()

    def is_stop_word(self, event):
        word = event[1]
        if word not in self._stop_words:
            self._event_manager.publish(('valid_word', word))

class WordFrequencyCounter:
    """ Keeps the word frequency data """
    def __init__(self, event_manager):
        self._word_freqs = {}
        self._event_manager = event_manager
        self._event_manager.subscribe('valid_word', self.increment_count)
        self._event_manager.subscribe('print', self.print_freqs)

    def increment_count(self, event):
        word = event[1]
        self._word_freqs[word] = self._word_freqs.get(word, 0) + 1        

    def print_freqs(self, event):
        print_word_freqs ( sort_dict (self._word_freqs) )      
        

class WordFrequencyApplication:
    def __init__(self, event_manager):
        self._event_manager = event_manager
        self._event_manager.subscribe('run', self.run)
        self._event_manager.subscribe('eof', self.stop)

    def run(self, event):
        path_to_file = event[1]
        self._event_manager.publish(('load', path_to_file))
        self._event_manager.publish(('start', None))

    def stop(self, event):
        self._event_manager.publish(('print', None))


if __name__ == "__main__":    
    em = EventManager()
    DataStorage(em), StopWordFilter(em), WordFrequencyCounter(em)
    WordFrequencyApplication(em)
    em.publish(('run', testfilepath ))