/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package org.biohackathon.SPARQLBuilder.OWL;

import com.hp.hpl.jena.query.*;
import com.hp.hpl.jena.sparql.engine.http.QueryEngineHTTP;
import java.util.*;

/**
 *
 * @author atsuko
 */
public class EndpointAccess {
    static public boolean checkPath(String startClass, List<ClassLink> classlinks, String sparqlEndpoint){
        // SPARQL Query construction
        StringBuilder queryStr = new StringBuilder();
        queryStr.append("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n");
	queryStr.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n");
        queryStr.append("ASK { \n");
        
        ListIterator<ClassLink> cit = classlinks.listIterator();
        queryStr.append("?r0").append(" rdf:type <").append(startClass).append("> .\n");
        int i = 0;
        while( cit.hasNext() ){
            ClassLink link = cit.next();
            //String next = link.getLinkedClassURI();
            String sval = "?r".concat(Integer.toString(i));
            String oval = "?r".concat(Integer.toString(i+1));
            queryStr.append(oval).append(" rdf:type <").append(link.getLinkedClassURI()).append("> .\n");
            if( link.getDirection() == Direction.forward ){
                queryStr.append(sval).append(" <").append(link.getPropertyURI()).append("> ")
                        .append(oval).append(" .\n");
            }else{
                queryStr.append(oval).append(" <").append(link.getPropertyURI()).append("> ")
                        .append(sval).append(" .\n");                
            }
            i++;
        }
        queryStr.append("} \n");
        
        String sparqlQuery = queryStr.toString();
        Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxARQ);
        /*
        QueryEngineHTTP httpQuery = new QueryEngineHTTP(sparqlEndpoint, query);
        boolean res = httpQuery.execAsk();
        httpQuery.close();
                */
        QueryExecution qexec = QueryExecutionFactory.sparqlService(sparqlEndpoint, query);
        boolean res = qexec.execAsk();
        qexec.close();
        return res;
    }
    
    static public boolean checkSimplePath(List<Integer> nodes, OWLClassGraph ocg, String sparqlEndpoint){
        // SPARQL Query construction
        StringBuilder queryStr = new StringBuilder();
        queryStr.append("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n");
	queryStr.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n");
        queryStr.append("ASK { \n");
        
        ListIterator<Integer> cit = nodes.listIterator();
        queryStr.append("?r0").append(" rdf:type <").append(ocg.labels.get(cit.next())).append("> .\n");
        int i = 0;
        while( cit.hasNext() ){
            String cURI = ocg.labels.get(cit.next());
            //String next = link.getLinkedClassURI();
            String sval = "?r".concat(Integer.toString(i));
            String pval = "?p".concat(Integer.toString(i));
            String oval = "?r".concat(Integer.toString(i+1));
            queryStr.append(oval).append(" rdf:type <").append(cURI).append("> .\n");
            queryStr.append("{{");
            queryStr.append(sval).append(" ").append(pval).append(" ")
                        .append(oval).append(" }\n UNION\n {");
            queryStr.append(oval).append(" ").append(pval).append(" ")
                        .append(sval).append(" }}\n");
            i++;
        }
        queryStr.append("} \n");
        
        String sparqlQuery = queryStr.toString();
        System.out.println("Ask Simple");
        System.out.println(sparqlQuery);
        Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxARQ);
        /*
        QueryEngineHTTP httpQuery = new QueryEngineHTTP(sparqlEndpoint, query);
        boolean res = httpQuery.execAsk();
        httpQuery.close();
                */
        QueryExecution qexec = QueryExecutionFactory.sparqlService(sparqlEndpoint, query);
        boolean res = qexec.execAsk();
        qexec.close();
        return res;
    }    

    static public boolean check3SimplePath(Integer node1, Integer node2, Integer node3, OWLClassGraph ocg, String sparqlEndpoint){
        // SPARQL Query construction
        StringBuilder queryStr = new StringBuilder();
        queryStr.append("PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n");
	queryStr.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n");
        queryStr.append("ASK { \n");
        
        queryStr.append("?n1").append(" rdf:type <").append(ocg.labels.get(node1)).append("> .\n");
        queryStr.append("?n2").append(" rdf:type <").append(ocg.labels.get(node2)).append("> .\n");
        queryStr.append("?n3").append(" rdf:type <").append(ocg.labels.get(node3)).append("> .\n");
        
        queryStr.append("{{");
            queryStr.append("?n1").append(" ").append("?p1").append(" ")
                        .append("?n2").append(" }\n UNION\n {");
            queryStr.append("?n2").append(" ").append("?p1").append(" ")
                        .append("?n1").append(" }}\n");

        queryStr.append("{{");
            queryStr.append("?n2").append(" ").append("?p2").append(" ")
                        .append("?n3").append(" }\n UNION\n {");
            queryStr.append("?n3").append(" ").append("?p2").append(" ")
                        .append("?n2").append(" }}\n");            
            
        queryStr.append("} \n");
        
        String sparqlQuery = queryStr.toString();
        System.out.println("Ask Simple3");
        System.out.println(sparqlQuery);
        Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxARQ);
        /*
        QueryEngineHTTP httpQuery = new QueryEngineHTTP(sparqlEndpoint, query);
        boolean res = httpQuery.execAsk();
        httpQuery.close();
                */
        QueryExecution qexec = QueryExecutionFactory.sparqlService(sparqlEndpoint, query);
        boolean res = qexec.execAsk();
        qexec.close();
        return res;
    }
    
    static public boolean check3SimplePathwithJoin(Integer node1, Integer node2, Integer node3, OWLClassGraph ocg, String sparqlEndpoint){
        StringBuilder queryStr = new StringBuilder();
	queryStr.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n");
        queryStr.append("SELECT DISTINCT ?n2 { \n");
        
        queryStr.append("?n1").append(" rdf:type <").append(ocg.labels.get(node1)).append("> .\n");
        queryStr.append("?n2").append(" rdf:type <").append(ocg.labels.get(node2)).append("> .\n");
        
        queryStr.append("{{");
            queryStr.append("?n1").append(" ").append("?p1").append(" ")
                        .append("?n2").append(" }\n UNION\n {");
            queryStr.append("?n2").append(" ").append("?p1").append(" ")
                        .append("?n1").append(" }}\n");

        queryStr.append("} \n");
        
        String sparqlQuery = queryStr.toString();
        System.out.println("SELECT Simple3 by Join");
        System.out.println(sparqlQuery);
        Query query = QueryFactory.create(sparqlQuery, Syntax.syntaxARQ);
        QueryExecution qexec = QueryExecutionFactory.sparqlService(sparqlEndpoint, query);
        ResultSet res1 = qexec.execSelect();
        qexec.close();
        
        queryStr = new StringBuilder();
	queryStr.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n");
        queryStr.append("SELECT DISTINCT ?n2 { \n");
        
        queryStr.append("?n2").append(" rdf:type <").append(ocg.labels.get(node2)).append("> .\n");
        queryStr.append("?n3").append(" rdf:type <").append(ocg.labels.get(node3)).append("> .\n");
        
        queryStr.append("{{");
            queryStr.append("?n2").append(" ").append("?p2").append(" ")
                        .append("?n3").append(" }\n UNION\n {");
            queryStr.append("?n3").append(" ").append("?p2").append(" ")
                        .append("?n2").append(" }}\n");

        queryStr.append("} \n");
        
        sparqlQuery = queryStr.toString();
        System.out.println("SELECT Simple3 by Join 2");
        System.out.println(sparqlQuery);
        query = QueryFactory.create(sparqlQuery, Syntax.syntaxARQ);
        qexec = QueryExecutionFactory.sparqlService(sparqlEndpoint, query);
        ResultSet res2 = qexec.execSelect();
        qexec.close();
        
        Set<String> res1hash = new HashSet<String>();
        while(res1.hasNext()){
            String resstr = res1.next().toString();
            res1hash.add(resstr);
        }
        while(res2.hasNext()){
            if ( res1hash.contains(res2.next().toString())){
                return true;
            }
        }
        return false;     
    }
}
