__author__ = 'Daan Debie'

from base_analyser import BaseAnalyser

class ProfileAnalyser(BaseAnalyser):
    """ Analyses profiles of twitter users and returns a dictionary
    with the most used words as keys and lists users whose profiles
    contain those words as value

    """
    profile_words = {}
    users = None
    profile_word_list = None

    # takes a list of TwitterUser models as argument
    def __init__(self, users):
        self.users = users

    #Filter a twitter profile's contents based on minimum word length
    def filter_words(self, profile, filter_length=3):
        # Replace possible separators by a regular space
        separator_chars = ['-', '|', '*', '&', ',', '.', '/', '~', '[', ']', '(', ')']
        filler_words = ['via', 'over', 'that', 'all', 'from', 'you', 'i\'m', 'are', 'van', 'bij', 'een', 'voor', 'and', 'the', 'with', 'met', 'niet', 'het', 'the', 'http:', 'www', 'com', 'for']
        for char in separator_chars:
            profile = profile.replace(char, ' ')
            # Split profile on spaces, lowercase the words and return them if applicable
        filtered_list = [e.lower() for e in profile.split() if len(e) >= filter_length and e.lower() not in filler_words]
        return filtered_list

    def analyse(self):
        total_users = len(self.users)
        # Take each user's profile, chop it up in seperate words
        for count, user in enumerate(self.users):
            #Wooohooo, I'm notifying all my observers now, m'kay?
            data = {}
            data['message'] = 'Processing (%(ucount)d/%(total)d): %(name)s' % {'ucount': count, 'total': total_users, 'name': user.screen_name}
            data['percentage'] = round((float(count)/total_users) * 100, 1)
            self.notifyAll(data)
            words = self.filter_words(user.profile)
            # Put those words as keys in a dictionary with as value the screen_names having that words in their profile
            for word in words:
                if word not in self.profile_words.keys():
                    self.profile_words[word] = set()
                self.profile_words[word].add(str(user.screen_name))

        # Sort the profilewords by length of the sets contained in it's values
        self.profile_word_list = sorted(self.profile_words.iteritems(), key=lambda (k, v): len(v), reverse=True)

        data['message'] = 'Processing done!'
        data['percentage'] = round(100)
        self.notifyAll(data)
        # Print top 20 words with associated users
        #        for word, users in profile_word_list[:20]:
        #            print word + ': ',
        #            for user in users:
        #                print user + ', ',
        #            print len(users),
        #            print '\n',

        return self.profile_word_list

    def result_to_string(self):
        result = ""
        for word, users in self.profile_word_list[:20]:
            result += word + ": "
            for user in users:
                result += "@" + user + " "
            result += "\n\n"
        return result