#!/usr/bin/env python
import argparse # optparse is deprecated
from itertools import islice # slicing for iterators
import re
from nltk.corpus import wordnet as wn
from collections import Counter
 
function_words = ["you", "i", "to", "the", "a", "and", "that", "it", "of", "me", "what", "is", "in", "this", "know", "i'm", "for", "no", "have", "my", "don't", "just", "not", "do", "be", "on", "your", "was", "we", "it's", "with", "so", "but", "all", "well", "are", "he", "oh", "about", "right"]


def word_matches(h, ref):
	total = 0
	for w in h:
#		print w
		if w in ref:
			total+=1
			continue
		hyp = wn.synsets(w)
		if hyp:
			h_syn = hyp[0]
		else:
			continue
		for r in ref:
			#see how similar they are in wordnet
			rr = wn.synsets(r)
			if rr:
				r_syn = rr[0]
			else:
				continue			
			sim = wn.path_similarity(h_syn, r_syn)
			if (sim > 0.1):
				total+=sim
			#TODO: check to see if the same POS
	return total

C_function = Counter(function_words)
for item in C_function.keys():
	C_function[item] = 10

def har_mean(p, r, a):
	den = (a * p + (1 - a) * r)
	if den == 0: return 0.0
	return p * r / den

def meteor(h, ref, alpha, delta):
	#shared function words
	m_function = float(sum((Counter(h) & Counter(ref) & C_function).viewvalues()))
	#shared content words
	m_content = float(word_matches(h,ref)) - m_function
	if not h:
		p = 0.0
	else:
		p = ((delta * m_content) + ((1 - delta) * m_function)) / len(h)
	if not ref:
		r = 0.0
	else:
		r = ((delta * m_content) + ((1 - delta) * m_function)) / len(ref)
	return har_mean(p,r,alpha)
 
def main():
	parser = argparse.ArgumentParser(description='Evaluate translation hypotheses.')
	# PEP8: use ' and not " for strings
	parser.add_argument('-i', '--input', default='data/train-test.hyp1-hyp2-ref',
			help='input file (default data/train-test.hyp1-hyp2-ref)')
	parser.add_argument('-n', '--num_sentences', default=None, type=int,
			help='Number of hypothesis pairs to evaluate')
	parser.add_argument('-a', '--alpha', default=0.5, type=float, help='precision/recall weight parameter')
	parser.add_argument('-d', '--delta', default=0.5, type=float, help='content/function word weight parameter')
	opts = parser.parse_args()
 
	def sentences():
		with open(opts.input) as f:
			for pair in f:
		#fixed preprocessing to remove punctuation and make lowercase
				yield [re.findall(r"[\w']+",sentence) for sentence in re.sub("\/"," ",re.sub("&quot;","",pair.lower().strip())).decode('unicode_escape').encode('ascii','ignore').split(' ||| ')]
# 				yield [sentence.strip().split() for sentence in pair.lower().split(' ||| ')]
	# note: the -n option does not work in the original code
	for h1, h2, ref in islice(sentences(), opts.num_sentences):
#		rset = set(ref)
#		h1_match = word_matches(h1, rset)
#		h2_match = word_matches(h2, rset)
#		print(-1 if h1_match > h2_match else # \begin{cases}
#				(0 if h1_match == h2_match
#					else 1)) # \end{cases}
		h1_val = meteor(h1, ref, opts.alpha, opts.delta)
		h2_val = meteor(h2, ref, opts.alpha, opts.delta)
	
		if h1_val != 0 and h2_val != 0:
			if (h1_val / h2_val) > 1.0002:
				print -1
			elif (h1_val / h2_val) <= 1.0002 and (h1_val / h2_val) >= 0.9998:
				print 0
			else:
				print 1
		elif h2_val == 0:
			print -1
		else:
			print 1
	 
# convention to allow import of this file as a module
if __name__ == '__main__':
	main()
