package eu.dnetlib.functionality.lightui.utils;

import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.dom.DOMSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.z3950.zing.cql.CQLNode;
import org.z3950.zing.cql.CQLOrNode;
import org.z3950.zing.cql.CQLParseException;
import org.z3950.zing.cql.CQLParser;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.ServiceLocator;

import java.io.*;
import java.util.List;

public class ODL_Utils {
	
	protected Log log = LogFactory.getLog(ODL_Utils.class);
	private DocumentBuilder parser;
	private String xsltPath = "";

	@Resource(name = "lookupLocator")
	ServiceLocator<ISLookUpService> lookupLocator;

	public ODL_Utils() throws ParserConfigurationException {
		parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
	}

	public ODL_Utils(String xsltpath) throws ParserConfigurationException {
		parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		xsltPath = xsltpath;
	}

	public String[] splitRepository(String query) {
	
		CQLParser parser = new CQLParser();
		try {
			CQLNode root = parser.parse(query);
				
			// TODO: do a proper recursive descent (perhaps by converting to XML)
			if (root instanceof CQLOrNode) {
				query = query.replaceAll("\\) or \\(", "|");
				query = query.replaceAll("\\(repositoryName = \"", "");
				query = query.replaceAll("repositoryName = \"", "");
				query = query.replaceAll("\"\\)", "");
				query = query.replaceAll("\"", "");

				return query.split("\\|");
			}				
		} catch (CQLParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return new String[] {}; 
	}

	public String cleanRepository(String docXML) {

		try {
			Document doc = parser.parse(new InputSource(new StringReader(docXML)));
			Element root = doc.getDocumentElement();
			String query = root.getTextContent();
			return query;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	public String viewDocument(String docXML) {

		try {
			Document doc = parser.parse(new InputSource(new StringReader(docXML)));
			DOMSource xmlDomSource = new DOMSource(doc);
			TransformerFactory tFactory = TransformerFactory.newInstance();
			Transformer transformer = tFactory.newTransformer(new StreamSource(
					xsltPath));
			// Transformer transformer = tFactory.newTransformer(new
			// javax.xml.transform.stream.StreamSource("howto.xsl"));
			StringWriter strw = new StringWriter();

			transformer.transform(xmlDomSource,
					new javax.xml.transform.stream.StreamResult(strw));

			return strw.toString();
			// transformer.transform(
			// new javax.xml.transform.stream.StreamSource("howto.xml"),
			// new javax.xml.transform.stream.StreamResult(StringWriter result);

			// transformer.transform(xmlDomSource, domResult);
			// System.out.println(domResult.toString());

		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	/* remove leading whitespace */
	public static String ltrim(String source) {
		return source.replaceAll("^\\s+", "");
	}

	/* remove trailing whitespace */
	public static String rtrim(String source) {
		return source.replaceAll("\\s+$", "");
	}

	/* remove all superfluous whitespaces in source string */
	public static String trim(String source) {
		return ltrim(rtrim(source));
	}

	public List<String> listItemsForVocabulary(String voc) throws ISLookUpException {
		return lookupLocator.getService().quickSearchProfile("//TERM[../../VOCABULARY_NAME='" + voc + "']/@english_name/string()");
	}
}
