/*
 * Created on 12.02.2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package test;

import java.io.IOException;
import java.util.Vector;

import org.openrdf.model.Value;
import org.openrdf.model.impl.GraphImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.sesame.Sesame;
import org.openrdf.sesame.config.AccessDeniedException;
import org.openrdf.sesame.config.ConfigurationException;
import org.openrdf.sesame.config.UnknownRepositoryException;
import org.openrdf.sesame.constants.QueryLanguage;
import org.openrdf.sesame.query.MalformedQueryException;
import org.openrdf.sesame.query.QueryEvaluationException;
import org.openrdf.sesame.query.QueryResultsTable;
import org.openrdf.sesame.repository.SesameRepository;
import org.openrdf.sesame.repository.SesameService;
import org.openrdf.vocabulary.RDF;

/**
 * @author mei
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class remote {


	static boolean flag = true;
	
	public static void main(String[] args) throws UnknownRepositoryException, ConfigurationException, QueryEvaluationException, IOException, MalformedQueryException, AccessDeniedException {

    	long startTime = System.currentTimeMillis();
		System.out.println("start: " + startTime);		
		
		java.net.URL sesameServerURL = new java.net.URL("http://"); // please write down the URL of the Sesame Server
		SesameService service = Sesame.getService(sesameServerURL);
		
		service.login("***", "****");	// please write down the login name and password
		
		//SesameRepository myInRepository = service.getRepository("rdbms-rdf-db");
		SesameRepository myInRepository = service.getRepository("rdbms-rdfs-db");
	
		String queryImp = "select rule, head, body from {rule} rdf:type {swrl:Imp}, {rule} swrl:head {head}, {rule} swrl:body {body} using namespace swrl = <http://www.w3.org/2003/11/swrl#>";
		QueryResultsTable tImp = myInRepository.performTableQuery(QueryLanguage.SERQL, queryImp);
		
		int rowCount = tImp.getRowCount();

		int num=0;
		while (flag) {
			flag = false;
			num++;
			System.out.println("******* hi... i am running *******###"+num+"'###");
		for (int row = 0; row <rowCount; row++) {
			Value rule = tImp.getValue(row, 0);
			Value head = tImp.getValue(row, 1);
			Value body = tImp.getValue(row, 2);
			Vector vhead = findList(head.toString(), myInRepository);
			Vector vbody = findList(body.toString(), myInRepository);
			inf(rule.toString(), vhead, vbody, myInRepository);
		}
		
    	long endTime = System.currentTimeMillis();
    	System.out.println("end : " + endTime);
		System.out.println("interval: " + (endTime-startTime));  		
		}
	}
	
	public static void inf(String r, Vector h, Vector b, SesameRepository myInRepository) throws QueryEvaluationException, IOException, MalformedQueryException, AccessDeniedException {
		Vector varList = new Vector();
		String[] atom = new String[3];
		for (int i=0; i<h.size(); i++) {
			atom = findAtom(h.get(i).toString(), myInRepository);
			if (atom[2].compareTo("null") != 0) {
				if (!varList.contains(atom[1])) varList.add(atom[1]); 
				if (!varList.contains(atom[2])) varList.add(atom[2]);
			}
			else if (!varList.contains(atom[1])) varList.add(atom[1]);
		}
		for (int i=0; i<b.size(); i++) {
			atom = findAtom(b.get(i).toString(), myInRepository);
			if (atom[2].compareTo("null") != 0) {
				if (!varList.contains(atom[1])) varList.add(atom[1]); 
				if (!varList.contains(atom[2])) varList.add(atom[2]);
			}
			else if (!varList.contains(atom[1])) varList.add(atom[1]);
		}		
		String query = "select ";
		query = query.concat(getID(varList.get(0)));
		int i = 1;
		while (i<varList.size()) {
			query = query.concat(", " + getID(varList.get(i)));
			i++;
		}
		query = query.concat(" from ");
		
		for (i=0; i<b.size(); i++) {
			atom = findAtom(b.get(i).toString(), myInRepository);
			if (atom[2].compareTo("null") != 0) {
				if ((atom[0].toString().compareTo("http://www.w3.org/2002/07/owl#differentFrom")!=0) &&
				(atom[0].toString().compareTo("http://www.w3.org/2002/07/owl#sameAs")!=0))
				query = query.concat("{"+getID(atom[1])+"} <"+atom[0]+"> {"+getID(atom[2])+"}, ");
			}
			else {
				query = query.concat("{"+getID(atom[1])+"} rdf:type {<"+atom[0]+">}, ");
			}
		}
		query = query.substring(0, query.length()-2);
		
		for (i=0; i<b.size(); i++) {
			atom = findAtom(b.get(i).toString(), myInRepository);
			if (atom[0].toString().compareTo("http://www.w3.org/2002/07/owl#differentFrom")==0) {
				query = query.concat(" where "+getID(atom[1])+" != "+getID(atom[2]));
			}
			if (atom[0].toString().compareTo("http://www.w3.org/2002/07/owl#sameAs")==0) {
				query = query.concat(" where "+getID(atom[1])+" = "+getID(atom[2]));
			}
		}
		
		System.out.println(query);
		
		GraphImpl result = new GraphImpl();
		
		QueryResultsTable tBinding = myInRepository.performTableQuery(QueryLanguage.SERQL, query);
		int rowCount = tBinding.getRowCount();
		int columnCount = tBinding.getColumnCount();
		int row, column;
		for (row = 0; row < rowCount; row++) {
		    for (column = 0; column < columnCount; column++) {
		        Value value = tBinding.getValue(row, column);
		        if (value != null) {System.out.print(value.toString());}
		        else {System.out.print("null");}
		        System.out.print("\t");
		    }
		    System.out.println();
		}	
		int s, o;
		URIImpl sub, pre, obj;
		String qHead = new String();
		QueryResultsTable tHead;
		for (i=0; i<h.size(); i++) {
			atom = findAtom(h.get(i).toString(), myInRepository);
			if (atom[2].compareTo("null") != 0) {
				s = varList.indexOf(atom[1]);
				o = varList.indexOf(atom[2]);
				for (row=0; row<rowCount; row++) {
					sub = new URIImpl(tBinding.getValue(row,s).toString());
					pre = new URIImpl(atom[0]);
					obj = new URIImpl(tBinding.getValue(row,o).toString());
					qHead = "select * from {s} p {o} where s=<"+sub+"> AND p=<"+pre+"> AND o=<"+obj+">";
					tHead = myInRepository.performTableQuery(QueryLanguage.SERQL, qHead);
					if (tHead.getRowCount()==0) {
						flag=true;
						result.add(sub,pre,obj);
						System.out.println(sub.toString()+"   ***   "+pre.toString()+"   ***   "+obj.toString());
					}
				}
			}
			else {
				s = varList.indexOf(atom[1]);
				for (row=0; row<rowCount;row++) {
					sub = new URIImpl(tBinding.getValue(row,s).toString());
					pre = new URIImpl(RDF.TYPE);
					obj = new URIImpl(atom[0]);
					qHead = "select * from {s} p {o} where s=<"+sub+"> AND p=<"+pre+"> AND o=<"+obj+">";
					tHead = myInRepository.performTableQuery(QueryLanguage.SERQL, qHead);
					if (tHead.getRowCount()==0) {
						flag = true;
						result.add(sub,pre,obj);
						System.out.println(sub.toString()+"   ***   "+pre.toString()+"   ***   "+obj.toString());
					}
				}
			}
		}
		myInRepository.addGraph(result);
	}
	
	public static String getID(Object str){
		String temp = str.toString();
		temp = temp.substring(temp.lastIndexOf("#")+1);
		return temp;
	}
	
	public static String[] findAtom(String atom, SesameRepository myInRepository) throws QueryEvaluationException, IOException, MalformedQueryException, AccessDeniedException {
		String qAtom = "select arg1, arg2, property, class from {a} swrl:argument1 {arg1}; [swrl:argument2 {arg2}]; [swrl:propertyPredicate {property}]; [swrl:classPredicate {class}] where a like \""+atom+"\" using namespace swrl = <http://www.w3.org/2003/11/swrl#>";
		QueryResultsTable tAtom = myInRepository.performTableQuery(QueryLanguage.SERQL, qAtom);
		String[] triple = new String[3];
		if (tAtom.getValue(0,2) != null) {
			triple[0] = tAtom.getValue(0,2).toString();
			triple[1] = tAtom.getValue(0,0).toString();
			triple[2] = tAtom.getValue(0,1).toString();
		}
		else if (tAtom.getValue(0,3) != null) {
			triple[0] = tAtom.getValue(0,3).toString();
			triple[1] = tAtom.getValue(0,0).toString();
			triple[2] = "null";
		}
		else {
			//triple[0] = "troublesome";
			triple[1] = tAtom.getValue(0,0).toString();
			triple[2] = tAtom.getValue(0,1).toString();
			String qEq = "select * from {a} rdf:type {c} where a like \""+atom+"\"" ;
			QueryResultsTable tEq = myInRepository.performTableQuery(QueryLanguage.SERQL, qEq);
			for (int row=0; row<tEq.getRowCount(); row++) {
				if (tEq.getValue(row, 1).toString().compareTo("http://www.w3.org/2003/11/swrl#DifferentIndividualsAtom")==0) {
					triple[0] = "http://www.w3.org/2002/07/owl#differentFrom";
					break;
				}
				if (tEq.getValue(row, 1).toString().compareTo("http://www.w3.org/2003/11/swrl#SameIndividualAtom")==0) {
					triple[0] = "http://www.w3.org/2002/07/owl#sameAs";
					break;
				}				
			}
		}
		return triple;
	}
	
	public static Vector findList(String list, SesameRepository myInRepository) throws QueryEvaluationException, IOException, MalformedQueryException, AccessDeniedException{
		Vector atomList = new Vector();
		while (list.compareTo("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil") != 0) {
			String qAtomlist = "select first, rest from {l} rdf:first {first}; rdf:rest {rest} where l like \""+list+"\"";
			QueryResultsTable tAtomList = myInRepository.performTableQuery(QueryLanguage.SERQL, qAtomlist);
			String first = tAtomList.getValue(0,0).toString();
			atomList.add(first); 
			//findAtom(first, myInRepository);
			list = tAtomList.getValue(0,1).toString();
		}
		return atomList;
	}

}
