#!/usr/bin/env python3
#!/usr/bin/python3 -W ignore::DeprecationWarning
# -*- coding:utf8 -*-
import sys
import spacy
import re
import codecs

from nltk.parse import CoreNLPParser
from nltk import sent_tokenize
from nltk.parse.corenlp import CoreNLPDependencyParser

dep_parser = CoreNLPDependencyParser(url='http://localhost:9000')
tagger = CoreNLPParser(url='http://localhost:9000')
tagger.parser_annotator='tokenize,ssplit,pos,lemma,ner,depparse,coref'
ner_tagger = CoreNLPParser(url='http://localhost:9000', tagtype='ner')

text = "jack is in the house"
question = "where is jack"


def resolve(corenlp_output):
    for coref in corenlp_output['corefs']:
        mentions = corenlp_output['corefs'][coref]
        antecedent = mentions[0]
        for j in range(1, len(mentions)):
            mention = mentions[j]
            if mention['type'] == 'PRONOMINAL':
                target_sentence = mention['sentNum']
                target_token = mention['startIndex'] - 1
                corenlp_output['sentences'][target_sentence - 1]['tokens'][target_token]['word'] = antecedent['text']

def output_resolved(corenlp_output):
    output = ""
    possessives = ['hers', 'his', 'their', 'theirs']
    for sentence in corenlp_output['sentences']:
        for token in sentence['tokens']:
            output_word = token['word']
            if token['lemma'] in possessives or token['pos'] == 'PRP$':
                output_word += "'s"
            output_word += token['after']
            output += output_word
    return output

def preprocessing(input_file):
    tagger = CoreNLPParser(url='http://localhost:9000')
    dep_parser = CoreNLPDependencyParser(url='http://localhost:9000')
    ner_tagger = CoreNLPParser(url='http://localhost:9000', tagtype='ner')
    parseResults = []
    ners = []
    with open(input_file, 'r') as f:
        for line in f:
            if not line or line == "\n":
                continue
            tagger.parser_annotator='tokenize,ssplit,pos,lemma,ner,depparse,coref'
            #timer = time.time()
            output = tagger.api_call(line)
            #print(str(len(line))+" used "+str(time.time()-timer))
            resolve(output)
            output = output_resolved(output)
            tokens = sent_tokenize(output)
            for token in tokens:
                parses = dep_parser.parse(token.split())
                ner = ner_tagger.tag(token.split())
                # print(list(ner))
                # print([[(governor, dep, dependent) for governor, dep, dependent in parse.triples()] for parse in parses])
                parseResults.append(parses)
                ners.append(ner)
    return parseResults, ners


def question_parser(question):
    question_dep = []
    first_word = question.split()[0].lower()
    question = question[0].lower() + question[1:]

    question_parses = dep_parser.parse(question.split())

    for parse in question_parses:       
        for governor, dep, dependent in parse.triples():
            question_dep.append((governor, dep, dependent))

    return question_dep, first_word

def nsubj_answer(text_dep, key_word):
    answer = None
    for (governor, dep, dependent) in text_dep:
        gov_word, gov_tag = governor
        dep_word, dep_tag = dependent
        if gov_word == key_word and dep == 'nsubj':
            answer = dep_word
        elif dep_word == key_word and dep == 'nsubj':
            answer = gov_word

    return answer

def yes_no_answer_from_dep_lists(text_dep, question_dep, first_word):
    key_word = None
    question_key_word = None
    answer = "No"

    for (governor, dep, dependent) in question_dep:
        gov_word, gov_tag = governor
        dep_word, dep_tag = dependent

        det_Tag = 'cop'

        if first_word in ["do","doing","did","done","does","can","could","will","should"]:
            det_Tag = 'aux'

        if dep_word == first_word and dep == det_Tag:
            question_key_word = gov_word
            break

    for (governor, dep, dependent) in question_dep:
        gov_word, gov_tag = governor
        dep_word, dep_tag = dependent 

        if gov_word == question_key_word and (dep == 'compound' or dep == 'nsubj'):
            key_word = dep_word
            break
        elif gov_word == question_key_word and dep == 'dobj':
            key_word = dep_word
            temp = key_word
            key_word = question_key_word
            question_key_word = temp
            break



    for (governor, dep, dependent) in text_dep:
        gov_word, gov_tag = governor
        dep_word, dep_tag = dependent

        if gov_word == question_key_word and (dep == 'nsubj' or dep == 'compound') and dep_word == key_word:
            answer = "Yes"
            break

    return answer




def wh_answer_from_dep_lists(text_dep, question_dep, wh_word):
    answer = None
    key_word = None

    is_doing = False
    is_where = False

    do_word_list = ["do","doing","did","done","does"]
    be_word_list = ["be","is","are","am","was","were"]

    for (governor, dep, dependent) in question_dep:
        gov_word, gov_tag = governor
        dep_word, dep_tag = dependent

        if gov_word == wh_word and dep == 'nsubj':
            key_word = dep_word
        elif dep_word == wh_word and dep == 'nsubj':
            key_word = gov_word

        ### 1 solve "what-do"
        if (gov_word in do_word_list) and dep == 'dobj' and dep_word == "what": 
            is_doing = True
            do_word = gov_word

        ### 2 solve "where"
        if dep == 'advmod' and dep_word == 'where' and (gov_word in be_word_list): 
            be_word = gov_word
            is_where = True

    answer = nsubj_answer(text_dep, key_word)

    ### 1 solve "what-do"
    if answer == None and is_doing:
        for (governor, dep, dependent) in question_dep:
            gov_word, gov_tag = governor
            dep_word, dep_tag = dependent

            if gov_word == do_word and dep == 'nsubj':
                key_word = dep_word

    answer = nsubj_answer(text_dep, key_word)

    ### 2 solve "where"
    if answer == None and is_where:
        for (governor, dep, dependent) in question_dep:
            gov_word, gov_tag = governor
            dep_word, dep_tag = dependent

            if gov_word == be_word and dep == 'nsubj':
                key_word = dep_word
    
    answer = nsubj_answer(text_dep, key_word)
    return answer

'''
question_dep, wh_word = question_parser(question)
answer = answer_from_dep_lists(text_dep, question_dep, wh_word)
print(answer)
print(text_dep)
print(question_dep)
'''


if __name__ == "__main__":
    input_file = sys.argv[1]
    question_file = sys.argv[2]

    # outfile = open("answer_output.txt", "w")

    parse_result, _ = preprocessing(input_file)

    text_parses = []

    text_dep = []

    for parses in parse_result:
        text_parses += parses

    for parse in text_parses:

        for governor, dep, dependent in parse.triples():
            text_dep.append((governor, dep, dependent))

    # print(text_dep)

    question_list = []

    with open(question_file, 'r')  as f:
        count = 0
        for line in f:
            count += 1
            question_list.append(line)
            # print('A'+str(count))

    yes_no = False

    for question in question_list:
        be_word_list = ["is","are","am","was","were"]
        do_word_list = ["do","doing","did","done","does","can","could","will","should"]
        question_dep, first_word = question_parser(question)
        # print(question_dep)
        if (first_word in be_word_list) or (first_word in do_word_list):
            yes_no = True

        if not yes_no:
            answer = wh_answer_from_dep_lists(text_dep, question_dep, first_word)
        else:
            answer = yes_no_answer_from_dep_lists(text_dep, question_dep, first_word)

        if answer == None:
            answer = "<No Answer>"
        print(answer)
        # outfile.write(answer+"\n")
        

