package org.aksw.simba.qaldbench.featurevectors;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.aksw.simba.benchmark.log.operations.CleanQueryReader;
import org.aksw.simba.qaldbench.centroid.KmeansPlusPlus;
import org.openrdf.query.BindingSet;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;
import org.openrdf.query.algebra.StatementPattern;
import org.openrdf.query.algebra.TupleExpr;
import org.openrdf.query.algebra.helpers.StatementPatternCollector;
import org.openrdf.query.parser.ParsedQuery;
import org.openrdf.query.parser.sparql.SPARQLParser;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.http.HTTPRepository;

public class FeatureVector {
	public static RepositoryConnection con ;
	public static Double [] maxIndexVal ;
	//public static final Map<String, Double[]> plainVectors;
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	public static Map<String, Double[]> getNormalizedFeaturesVectors(String endpointURL, String queryFile) throws RepositoryException, MalformedQueryException, QueryEvaluationException, IOException {
		initializeRepo(endpointURL);
		 String queryString = getQuery(queryFile);
		 Map<String, Double[]> vectors = new HashMap<String,Double[]>();
		  TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
		  TupleQueryResult result = tupleQuery.evaluate();
		  int vectorLength = result.getBindingNames().size()-1;
		  maxIndexVal = new Double[vectorLength]; 
		 for(int i=0;i<vectorLength;i++)
				maxIndexVal[i] = 0d;
		  while(result.hasNext()){
			   BindingSet bset = result.next();
		//	if(!isSingleTpSPOQuery(bset)){
			  String key= bset.getBinding("qId").getValue().toString().replace("http://qald-gen.aksw.org/question#", "");
			  Set<String> bindings = bset.getBindingNames();
				Double[] vector = new Double[vectorLength];
				int i = 0;
				for(String binding:bindings){
					if(!binding.equals("qId")){
				vector[i] = getDoubleValue(bset,binding);
				if(maxIndexVal[i]<vector[i])
					maxIndexVal[i] = vector[i];
				i++;
				} }
				vectors.put(key, vector);
			//  }
		  }
	    con.close();
		return CleanQueryReader.getNormalizedVectors(vectors,maxIndexVal);
	}

	public static void initializeRepo(String endpointURL) throws RepositoryException {
		Repository repo = new HTTPRepository(endpointURL, "sqcbench");
		repo.initialize();
		 con = repo.getConnection();		
	}

	public static boolean isSingleTpSPOQuery(BindingSet bset) throws RepositoryException, MalformedQueryException, QueryEvaluationException {
		if(getIntValue(bset, "tps")==1){
			String supQueryURI = "<"+bset.getBinding("sup").getValue().stringValue()+">";
			String queryString = "Prefix lsq: <http://lsq.aksw.org/vocab#> \n"
					+ "SELECT DISTINCT  ?supText \n "
					+ "{ \n"
									+  supQueryURI + " lsq:text ?supText .  \n"
									+ "}";
			  TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
			  TupleQueryResult result = tupleQuery.evaluate();
			  String supQryStr = result.next().getBinding("supText").getValue().stringValue();
			 // tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, supQryStr);
			  SPARQLParser parser = new SPARQLParser();
				ParsedQuery parsedQuery = parser.parseQuery(supQryStr, null);
				TupleExpr query = parsedQuery.getTupleExpr();
		  List<StatementPattern> patterns = StatementPatternCollector.process(query);
		  for(StatementPattern stmt:patterns)
		  {
			  if(stmt.getSubjectVar().getValue()==null && stmt.getObjectVar().getValue()==null && stmt.getPredicateVar().getValue()==null)
				  return true;
		  }
		}
		return false;
		
			
		
		//return false;
	}

	private static Double getDoubleValue(BindingSet bset, String binding) {
		String value  = bset.getBinding(binding).getValue().toString();
		String [] prts = value.split("\"");
		Double val = Double.parseDouble(prts[1]);
		return val;
	}
	
	private static int getIntValue(BindingSet bset, String binding) {
		String value  = bset.getBinding(binding).getValue().toString();
		String [] prts = value.split("\"");
		int val = Integer.parseInt((prts[1]));
		return val;
	}

	/**
	 * Load query string from file
	 * @param qryFile Query File
	 * @return query Query string
	 * @throws IOException
	 */
	public static String  getQuery(String fileStr) throws IOException {
		File qryFile = new File(fileStr);
		String query = "" ; 
		BufferedReader br = new BufferedReader(new FileReader(qryFile));
		String line;
		while ((line = br.readLine()) != null)
		{
			query = query+line+"\n";
		}
	    br.close();
		return query;
	}
}
