package eventdetection.validator.implementations;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

import edu.stanford.nlp.ling.CoreAnnotations.SentencesAnnotation;
import edu.stanford.nlp.ling.CoreAnnotations.TokensAnnotation;
import edu.stanford.nlp.ling.CoreLabel;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.util.CoreMap;
import eventdetection.common.Article;
import eventdetection.common.Query;
import eventdetection.validator.ValidationResult;
import eventdetection.validator.Validator;
import eventdetection.validator.ValidatorController;

public class SwoogleSemanticAnalysisValidator extends Validator {
	private static final String URL_PREFIX = "http://swoogle.umbc.edu/StsService/GetStsSim?operation=api";
	
	/**
	 * Constructs a new instance of the {@link Validator} for the given {@code ID}, {@link Query}, and {@link Article}
	 * 
	 * @param algorithmID
	 *            the {@code ID} of the implemented algorithm as determined by the {@link ValidatorController}
	 * @param query
	 *            the {@link Query} to validate
	 * @param article
	 *            the {@link Article} against which the {@link Query} is to be validated
	 */
	public SwoogleSemanticAnalysisValidator(Integer algorithmID, Query query, Article article) {
		super(algorithmID, query, article);
	}
	
	@Override
	public ValidationResult call() throws IOException {
		StringBuilder phrase1 = new StringBuilder();
		phrase1.append(query.getSubject()).append(" ").append(query.getVerb());
		if (query.getDirectObject() != null && query.getDirectObject().length() > 0)
			phrase1.append(" ").append(query.getDirectObject());
		if (query.getIndirectObject() != null && query.getIndirectObject().length() > 0)
			phrase1.append(" ").append(query.getIndirectObject());
		double most = 0.0;
		for (Annotation paragraph : article.getAnnotatedText()) {
			List<CoreMap> sentences = paragraph.get(SentencesAnnotation.class);
			for (CoreMap sentence : sentences) {
				String sen = reconstructSentence(sentence);
				String url = String.format("%s&phrase1=%s&phrase2=%s", URL_PREFIX, URLEncoder.encode(phrase1.toString(), StandardCharsets.UTF_8.name()),
						URLEncoder.encode(sen, StandardCharsets.UTF_8.name()));
				URLConnection connection = new URL(url).openConnection();
				connection.setRequestProperty("Accept-Charset", StandardCharsets.UTF_8.name());
				try (BufferedReader response = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
					double temp = Double.parseDouble(response.readLine().trim());
					if (temp > most)
						most = temp;
				}
			}
		}
		return new ValidationResult(this.getID(), article.getID(), most);
	}
	
	private static String reconstructSentence(CoreMap sentence) {
		StringBuilder sb = new StringBuilder();
		// traversing the words in the current sentence
		// a CoreLabel is a CoreMap with additional token-specific methods
		List<CoreLabel> tokens = sentence.get(TokensAnnotation.class);
		for (CoreLabel token : tokens)
			sb.append(token.word()).append(" ");
		return sb.toString().trim();
	}
}

@@ -756,16 +756,163 @@
 oller;%0A%0A
+import toberumono.structures.tuples.Pair;%0Aimport toberumono.structures.collections.lists.SortedList;%0Aimport toberumono.structures.SortingMethods;%0A%0A
 public c
@@ -2123,16 +2123,125 @@
  = 0.0;%0A
+        SortedList%3CPair%3CDouble, String%3E%3E topFive = new SortedList%3C%3E((a, b) -%3E b.getX().compareTo(a.getX()));%0A
 %09%09for (A
@@ -2914,17 +2914,17 @@
  %7B%0A%09%09%09%09%09
-d
+D
 ouble te
@@ -2980,63 +2980,336 @@
 ));%0A
-%09%09%09%09%09if (temp %3E most)%0A%09%09%09%09%09%09most = temp;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D
+                    topFive.add(new Pair%3C%3E(temp, sen));%0A                    if (topFive.size() %3E 5)%0A                        topFive.remove(topFive.size() - 1);%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A        double average = 0.0;%0A        for (Pair%3CDouble, String%3E p : topFive)%0A            average += p.getX();%0A        average /= (double) topFive.size();
 %0A%09%09r
@@ -3366,20 +3366,23 @@
 etID(), 
-most
+average
 );%0A%09%7D%0A%09%0A

Change from using Max to average of Top 5 sent