package cz.brmlab.yodaqa.provider.rdf;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import com.hp.hpl.jena.rdf.model.Literal;

import net.sf.extjwnl.data.IndexWord;
import net.sf.extjwnl.data.Word;
import net.sf.extjwnl.dictionary.Dictionary;
import net.sf.extjwnl.data.PointerTarget;
import net.sf.extjwnl.data.PointerType;
import net.sf.extjwnl.data.Synset;
import net.sf.extjwnl.data.BaseDictionaryElement;
import net.sf.extjwnl.JWNLException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;

/** A wrapper around DBpedia dataset that maps concepts to
 * dbpedia2:wordnet_type ontology pieces. This gives some evidence
 * of the type of the concept that we directly match with other
 * WordNet data.
 *
 * XXX: The WordNet types here also disambiguate word senses.
 * We drop this information for now, instead of converting this
 * to synset numbers. */

public class DBpediaWNTypes extends CachedJenaLookup {
	private static final Log logger = LogFactory.getLog(DBpediaWNTypes.class);
	
	Dictionary dictionary = null;
	
	public void initialize() throws JWNLException 
	{
	    try
	    {	
		/**
		 * New style initialize librarary ExtJWNL.
		 */
		dictionary = Dictionary.getDefaultResourceInstance();
	    } 
	    catch (Exception e) 
	    {
			e.printStackTrace();
	    }
	}
	
	/** Query for a given title, returning a set of types. The type is in
	 * the form of string/synset. */
	public List<String> query(String title, Logger logger) {
		for (String titleForm : cookedTitles(title)) {
			List<String> results = queryTitleForm(titleForm, logger);
			if (!results.isEmpty())
				return results;
		}
		return new ArrayList<String>();
	}

	/** Query for a given specific title form, returning a set
	 * of types. The type is in the form of string/synset. */
	public List<String> queryTitleForm(String title, Logger logger) {
		/* XXX: Case-insensitive search via SPARQL turns out
		 * to be surprisingly tricky.  Cover 90% of all cases
		 * by force-capitalizing the first letter in the sought
		 * after title. */
		title = Character.toUpperCase(title.charAt(0)) + title.substring(1);

		title = title.replaceAll("\"", "").replaceAll("\\\\", "").replaceAll("\n", " ");
		String rawQueryStr =
			"{\n" +
			   // (A) fetch resources with @title label
			"  ?res rdfs:label \"" + title + "\"@en.\n" +
			"} UNION {\n" +
			   // (B) fetch also resources targetted by @title redirect
			"  ?redir dbo:wikiPageRedirects ?res .\n" +
			"  ?redir rdfs:label \"" + title + "\"@en .\n" +
			"}\n" +
			 // set the output variable
			"?res dbpedia2:wordnet_type ?type .\n" +

			 // weed out resources that are categories and other in-namespace junk
			"FILTER ( !regex(str(?res), '^http://dbpedia.org/resource/[^_]*:', 'i') )\n" +
			"";
		//logger.debug("executing sparql query: {}", rawQueryStr);
		List<Literal[]> rawResults = rawQuery(rawQueryStr,
			new String[] { "type" });

		List<String> results = new LinkedList<String>();
		for (Literal[] rawResult : rawResults) {
			// XXX: we assume the type is always noun
			int senseIdx = Integer.parseInt(rawResult[0].getString().replaceAll("^.*-([^-]*)$", "$1"));
			String typeLabel = rawResult[0].getString().replaceAll("^synset-([^-]*)-.*$", "$1").replaceAll("_", " ");

			try {
				IndexWord w = dictionary.getIndexWord(net.sf.extjwnl.data.POS.NOUN, typeLabel);
				Synset s = w.getSenses().get(senseIdx - 1);
				long synset = s.getOffset();

				// logger.debug("DBpedia {} wntype: [[{}]]", title, typeLabel);
				results.add(typeLabel + "/" + Long.toString(synset));
			} catch (Exception e) {
				logger.debug("DBpedia {} wntype [[{}]] exception: {}", title, typeLabel, e);
			}
		}

		return results;
	}
}

@@ -634,24 +634,89 @@
 LogFactory;%0A
+import org.apache.uima.resource.ResourceInitializationException;%0A
 import org.s
@@ -1290,20 +1290,38 @@
  throws 
-JWNL
+ResourceInitialization
 Exceptio
@@ -1325,87 +1325,21 @@
 tion
- 
 %0A%09%7B%0A%09
-    try%0A%09   
+%09try
  %7B
-%09
 %0A%09
-%09/**%0A%09%09 * New style initialize librarary ExtJWNL.%0A%09%09 */%0A
 %09%09di
@@ -1395,27 +1395,18 @@
 );%0A%09
-    %7D %0A%09   
+%09%7D
  catch (
 Exce
@@ -1393,32 +1393,36 @@
 e();%0A%09%09%7D catch (
+JWNL
 Exception e) %0A%09 
@@ -1422,45 +1422,61 @@
  e) 
-%0A%09    %7B%0A%09%09%09e.printStackTrace();%0A%09    
+%7B%0A%09%09%09throw new ResourceInitializationException(e);%0A%09%09
 %7D%0A%09%7D

Make initialize() re-throw standard exception, style cleanup