package eu.dnetlib.dlms.jdbc.parser;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collection;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import eu.dnetlib.dlms.jdbc.ast.Statement;
import groovy.lang.GroovyShell;
import groovy.util.XmlSlurper;
import groovy.util.slurpersupport.GPathResult;

/**
 * Class to parse Doroty Language strings.
 * 
 * @author alessia
 * 
 */
public class DQLParser implements IDQLParser {

	/** Default URL to connect to the haskell parser. */
	public static String DEFAULT_CONN_URL = "http://node1.integration.driver.research-infrastructures.eu:9999";
	/**
	 * URL to connect to the haskell parser. Its default value is DEFAULT_CONN_URL.
	 */
	private String connectionURL = DEFAULT_CONN_URL;

	public String getConnectionURL() {
		return connectionURL;
	}

	public void setConnectionURL(final String connectionURL) {
		this.connectionURL = connectionURL;
	}

	public DQLParser() {

	}

	public DQLParser(final String url) {
		this.setConnectionURL(url);
	}

	/**
	 * Post method through an URLConnection.
	 * 
	 * @param url
	 *            string which is the target url of the post
	 * @param body
	 *            string containing the body of the post request
	 * @return the response of the POST request
	 * @throws IOException
	 *             connecting to url for the post request
	 */
	private InputStream post(final String url, final String body) throws IOException {
		URL theURL = new URL(url);
		URLConnection conn = theURL.openConnection();
		conn.setRequestProperty("method", "POST");
		conn.setDoOutput(true);
		Writer wr = new OutputStreamWriter(conn.getOutputStream());
		wr.write(body);
		wr.flush();
		wr.close();
		conn.connect();
		System.out.println("The content type of the urlConnection is " + conn.getContentType());
		Object content = conn.getContent();
		System.out.println("Content.toString() == " + content.toString());
		return (InputStream) content;
	}

	/**
	 * Parses the given string to build the corresponding abstract syntax tree.
	 * 
	 * @param dql
	 *            DorotyLanguage string to parse
	 * @return the root for the AST generated by the parsing of dql
	 * @throws IOException
	 *             executing the post request
	 * @throws SAXException
	 *             parsing the string
	 * @throws ParserConfigurationException
	 *             parsing the string
	 */
	@SuppressWarnings("unchecked")
	public Collection<Statement> parse(final String dql) {
		try {
			InputStream postRes = this.post(this.connectionURL, dql);
			System.out.println("result from post: \n" + postRes);
			GPathResult records = new XmlSlurper().parse(postRes);
			String asText = records.text();
			System.out.println("Now evaluating " + asText + "\n ...");
			return (Collection<Statement>) new GroovyShell().evaluate("import eu.dnetlib.dlms.jdbc.ast.*; " + asText);
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
	}

}
