package ua.be.wee.model.repository;

import java.util.ArrayList;
import java.util.List;

import org.apache.jena.query.QuerySolution;
import org.apache.jena.query.ResultSet;
import org.apache.jena.rdf.model.RDFNode;
import org.springframework.stereotype.Repository;

import ua.be.wee.model.nodes.Node;
import ua.be.wee.model.pm.PM;
import ua.be.wee.model.util.Pair;

@Repository
public class PMRepository {

	public List<PM> getAllPMs() {
		String query = "PREFIX pm: <http://ua.be/sdo2l/vocabulary/formalisms/pm#>\n"
				+ "PREFIX base: <http://ua.be/sdo2l/vocabulary/base#>\n"
				+ "PREFIX obj: <http://ua.be/sdo2l/vocabulary/formalisms/object_diagram#>\n"
				+ "SELECT ?pm ?pmName WHERE {\n"
				+ "  ?pm a pm:Model ;\n"
				+ "  	obj:hasName ?pmName .\n"
				+ "}";
		ResultSet results = FusekiWrapper.getInstance().execQuery(query);
		List<PM> list = new ArrayList<PM>();
		while (results.hasNext()) {
			PM pm = new PM();
			QuerySolution soln = results.nextSolution();
			RDFNode iri = soln.get("?pm");
			RDFNode name = soln.get("?pmName");
			pm.setIri(iri.toString());
			pm.setName(name.toString());
			list.add(pm);
		}
		return list;
	}

	public PM getPM(String pmiri) throws Exception {
		String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
				+ "PREFIX pm: <http://ua.be/sdo2l/vocabulary/formalisms/pm#>\n"
				+ "PREFIX obj: <http://ua.be/sdo2l/vocabulary/formalisms/object_diagram#>\n"
				+ "SELECT ?pm ?pmName WHERE {\n"
				+ "  ?pm a pm:Model ;\n"
				+ "  	obj:hasName ?pmName ;\n"
				+ "  	owl:sameAs <" + pmiri + "> .\n"
				+ "}";
		ResultSet results = FusekiWrapper.getInstance().execQuery(query);
		
		if (results.hasNext()) {
			PM pm = new PM();
			QuerySolution soln = results.nextSolution();
			RDFNode iri = soln.get("?pm");
			RDFNode name = soln.get("?pmName");
			pm.setIri(iri.toString());
			pm.setName(name.toString());
			return pm;
		} else {
			throw new Exception("No data returned by query: \n" + query );
		}
		
	}

	public List<Pair<String,String>> findNextNodes(String iri) {
		List<Pair<String,String>> list = new ArrayList<Pair<String,String>>();
		String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n"
				+ "PREFIX pm: <http://ua.be/sdo2l/vocabulary/formalisms/pm#>\n"
				+ "SELECT ?e ?nodetype ?act WHERE {\n"
				+ "  ?node owl:sameAs <" + iri + "> .\n"
				+ "  ?node pm:ctrlTo+ ?e .\n"
				+ "  ?e a ?nodetype ;\n"
				+ "  FILTER (?nodetype in (pm:CtrlInputPort, pm:Final)) \n"
				+ "	 OPTIONAL {\n"
				+ "		?e pm:ofActivity ?act .\n"
				+ "	 }\n"
				+ "}";
		ResultSet results = FusekiWrapper.getInstance().execQuery(query);
		while (results.hasNext()) {
			QuerySolution soln = results.nextSolution();
			RDFNode type = soln.get("?nodetype");
			Pair<String,String> pair;
			if (type.toString().equals(Node.CTRL_INPUT_PORT_IRI)) {
				pair = new Pair<String,String>(soln.get("?e").toString(),soln.get("?act").toString());
			} else {
				pair = new Pair<String,String>(soln.get("?e").toString(), null);
			}
			list.add(pair);
			
		}
		return list;
	}	
	
}
