from __future__ import print_function
import re
import sys
import time

from structures import BTree, LinkedList

lexicon = LinkedList()
tree = BTree(4)
special_tree = BTree(10)

def create_linked_list():
    print('Creating Linked List Lexicon')
    with open(sys.argv[2], 'r') as dictionary:
        for word in dictionary:
            lexicon.insert(re.sub('\W+', '', word).lower())

def spell_check_linked_list():
    print('Spell Checking {0}'.format(sys.argv[1]))
    misspelled = 0
    start = time.time()
    with open(sys.argv[1], 'r') as file:
        words = re.sub('\W+', ' ', file.read()).split(' ')
        for i in range(len(words)):
            if len(words[i]) > 0:
                found = lexicon.search(words[i].lower().strip())
                if not found:
                    misspelled += 1
    end = time.time()
    print('There are {0} misspelled words in {1}'.format(misspelled, sys.argv[1]))
    print('Time Elapsed: {0}'.format(end - start))
    frequent = lexicon.find_max()
    print('Highest Frequency Word: {0}'.format(frequent.word))
    print('Count: {0}'.format(frequent.count))
    print('')

def remove_words_linked_list():
    print('Removing words from Linked List Lexicon')
    with open(sys.argv[3], 'r') as dictionary:
        for word in dictionary:
            lexicon.remove(re.sub('\W+', '', word).lower())

def create_btree():
    print('Creating BTree Lexicon, m = 4')
    with open(sys.argv[2], 'r') as dictionary:
        for word in dictionary:
            tree.insert(re.sub('\W+', '', word).lower())

def spell_check_btree():
    print('Spell Checking {0}'.format(sys.argv[1]))
    misspelled = 0
    start = time.time()
    with open(sys.argv[1], 'r') as file:
        words = re.sub('\W+', ' ', file.read()).split(' ')
        for i in range(len(words)):
            if len(words[i]) > 0:
                found = tree.search(words[i].lower().strip())
                if not found:
                    misspelled += 1
    end = time.time()
    print('There are {0} misspelled words in {1}'.format(misspelled, sys.argv[1]))
    print('Time Elapsed: {0}'.format(end - start))
    frequent = tree.find_max()
    print('Highest Frequency Word: {0}'.format(frequent.word))
    print('Count: {0}'.format(frequent.count))
    print('')

def remove_words_btree():
    print('Removing words from BTree Lexicon, m = 4')
    with open(sys.argv[3], 'r') as dictionary:
        for word in dictionary:
            tree.remove(re.sub('\W+', '', word).lower())

def create_special_tree():
    print('Creating BTree Lexicon, m = 10')
    with open(sys.argv[2], 'r') as dictionary:
        for word in dictionary:
            special_tree.insert(re.sub('\W+', '', word).lower())

def spell_check_special_tree():
    print('Spell Checking {0}'.format(sys.argv[1]))
    misspelled = 0
    start = time.time()
    with open(sys.argv[1], 'r') as file:
        words = re.sub('\W+', ' ', file.read()).split(' ')
        for i in range(len(words)):
            if len(words[i]) > 0:
                found = special_tree.search(words[i].lower().strip())
                if not found:
                    misspelled += 1
    end = time.time()
    print('There are {0} misspelled words in {1}'.format(misspelled, sys.argv[1]))
    print('Time Elapsed: {0}'.format(end - start))
    frequent = special_tree.find_max()
    print('Highest Frequency Word: {0}'.format(frequent.word))
    print('Count: {0}'.format(frequent.count))
    print('')

def remove_words_special_tree():
    print('Removing words from BTree Lexicon, m = 10')
    with open(sys.argv[3], 'r') as dictionary:
        for word in dictionary:
            special_tree.remove(re.sub('\W+', '', word).lower())

if __name__ == '__main__':
    create_linked_list()
    spell_check_linked_list()

    create_btree()
    spell_check_btree()

    create_special_tree()
    spell_check_special_tree()

    # this is commented out because it takes too much time
    # the linked list uses a tail to reduce insertion time from
    # O(n) to O(1) but removal is still O(n).  Removing ~23000 words
    # from a linked list of 230000+ words would take a long time
    # remove_words_linked_list()
    # spell_check_linked_list()

    remove_words_special_tree()
    spell_check_special_tree()
