package org.aksw.sparqlify.qa.metrics.availability;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Set;

import org.aksw.sparqlify.core.algorithms.ViewQuad;
import org.aksw.sparqlify.core.domain.input.ViewDefinition;
import org.aksw.sparqlify.qa.exceptions.NotImplementedException;
import org.aksw.sparqlify.qa.metrics.NodeMetric;
import org.aksw.sparqlify.qa.metrics.PinpointMetric;
import org.aksw.sparqlify.qa.sinks.TriplePosition;

import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.graph.Node_URI;
import com.hp.hpl.jena.graph.Triple;


public class DereferenceableForwardLinks extends PinpointMetric implements
		NodeMetric {

	private HashMap<String, Boolean> linkBroken;


	public DereferenceableForwardLinks() {
		linkBroken = new HashMap<String, Boolean>();
	}
	
	@Override
	public void assessNodes(Triple triple) throws NotImplementedException {
		// FIXME: make this threaded
		
		Node subject = triple.getSubject();
		if (subject.isURI() && !((Node_URI) subject).getURI().startsWith(prefix)
				&& isBroken((Node_URI) subject)) {
			
			Set<ViewQuad<ViewDefinition>> viewQuads =
					pinpointer.getViewCandidates(triple);
			
			writeNodeMeasureToSink(0, TriplePosition.SUBJECT, triple, viewQuads);
		}
		
		Node predicate = triple.getPredicate();
		if (!((Node_URI) predicate).getURI().startsWith(prefix)
				&& isBroken((Node_URI) predicate)) {
			
			Set<ViewQuad<ViewDefinition>> viewQuads =
					pinpointer.getViewCandidates(triple);
			
			writeNodeMeasureToSink(0, TriplePosition.PREDICATE, triple, viewQuads);
		}
		
		Node object = triple.getObject();
		if (object.isURI() && !((Node_URI) object).getURI().startsWith(prefix) && isBroken((Node_URI) object)) {
			Set<ViewQuad<ViewDefinition>> viewQuads =
					pinpointer.getViewCandidates(triple);
			
			writeNodeMeasureToSink(0, TriplePosition.OBJECT, triple, viewQuads);
		}
	}


	private boolean isBroken(Node_URI node) {
		
		Boolean broken = linkBroken.get(node.getURI());
		
		if (broken != null) {
			return broken;
		} else {
			URL extUrl;
			try {
				// FIXME: 
				extUrl = new URL(node.getURI());
			} catch (MalformedURLException e) {
				linkBroken.put(node.getURI(), true);
				return true;
			}
			
			URLConnection urlConn;
			try {
				urlConn = extUrl.openConnection();
			} catch (IOException e) {
				linkBroken.put(node.getURI(), true);
				return true;
			}
			
			if (urlConn.getContentType() != null) {
				linkBroken.put(node.getURI(), false);
				return false;
			} else {
				linkBroken.put(node.getURI(), true);
				return true;
			}
		}
	}

}

@@ -50,39 +50,8 @@
 y;%0A%0A
-import java.io.BufferedReader;%0A
 impo
@@ -90,28 +90,29 @@
 ava.
-io.InputStreamReader
+net.HttpURLConnection
 ;%0Aim
@@ -164,19 +164,33 @@
 ava.net.
-URL
+ProtocolException
 ;%0Aimport
@@ -202,26 +202,16 @@
 .net.URL
-Connection
 ;%0Aimport
@@ -2346,16 +2346,20 @@
 %0A%09%09%09%0A%09%09%09
+Http
 URLConne
@@ -2373,16 +2373,20 @@
 rlConn;%0A
+%09%09%09%0A
 %09%09%09try %7B
@@ -2399,16 +2399,36 @@
 rlConn =
+ (HttpURLConnection)
  extUrl.
@@ -2548,44 +2548,401 @@
 %0A%09%09%09
-if (urlConn.getContentType() != null
+try %7B%0A%09%09%09%09urlConn.setRequestMethod(%22GET%22);%0A%09%09%09%7D catch (ProtocolException e) %7B%0A%09%09%09%09linkBroken.put(node.getURI(), true);%0A%09%09%09%09return true;%0A%09%09%09%7D%0A%09%09%09%0A%09%09%09int responseCode = 0;%0A%09%09%09%0A%09%09%09try %7B%0A%09%09%09%09urlConn.connect();%0A%09%09%09%09responseCode = urlConn.getResponseCode();%0A%09%09%09%7D catch (IOException e) %7B%0A%09%09%09%09linkBroken.put(node.getURI(), true);%0A%09%09%09%09return true;%0A%09%09%09%7D%0A%0A%09%09%09if (responseCode %3E= 200 && responseCode %3C 400
 ) %7B%0A

fix for DereferenceableForwardLinks metric