package eu.dnetlib.msro.workflows.nodes.db;

import java.io.IOException;

import javax.annotation.Resource;
import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import com.googlecode.sarasvati.Arc;
import com.googlecode.sarasvati.NodeToken;

import eu.dnetlib.enabling.database.rmi.DatabaseService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.msro.workflows.nodes.AsyncJobNode;

public class QueryDbJobNode extends AsyncJobNode {

	private String db;
	private String dbParam;
	private String dbProperty;

	private String sql;
	private String sqlForSize;
	private String xslt;
	private String outputEprParam;

	@Resource
	private UniqueServiceLocator serviceLocator;

	@Override
	protected String execute(final NodeToken token) throws Exception {
		final String sqlText = fetchSqlAsText(sql);

		W3CEndpointReference epr = null;

		final DatabaseService dbService = serviceLocator.getService(DatabaseService.class);

		if (StringUtils.isNotBlank(xslt)) {
			final String xsltText = IOUtils.toString(getClass().getResourceAsStream(xslt));

			if (StringUtils.isBlank(sqlForSize)) {
				epr = dbService.xsltSearchSQL(findDb(token), sqlText, xsltText);
			} else {
				epr = dbService.alternativeXsltSearchSQL(findDb(token), sqlText, fetchSqlAsText(sqlForSize), xsltText);
			}
		} else {
			if (StringUtils.isBlank(sqlForSize)) {
				epr = dbService.searchSQL(findDb(token), sqlText);
			} else {
				epr = dbService.alternativeSearchSQL(findDb(token), sqlText, fetchSqlAsText(sqlForSize));
			}
		}

		token.getEnv().setAttribute(outputEprParam, epr.toString());

		return Arc.DEFAULT_ARC;
	}

	private String fetchSqlAsText(final String path) throws IOException {
		return IOUtils.toString(getClass().getResourceAsStream(path));
	}

	private String findDb(final NodeToken token) {
		if (dbParam != null && !dbParam.isEmpty()) {
			return token.getEnv().getAttribute(dbParam);
		} else if (dbProperty != null && !dbProperty.isEmpty()) {
			return getPropertyFetcher().getProperty(dbProperty);
		} else {
			return db;
		}
	}

	public String getDb() {
		return db;
	}

	public void setDb(final String db) {
		this.db = db;
	}

	public String getDbParam() {
		return dbParam;
	}

	public void setDbParam(final String dbParam) {
		this.dbParam = dbParam;
	}

	public String getSql() {
		return sql;
	}

	public void setSql(final String sql) {
		this.sql = sql;
	}

	public String getXslt() {
		return xslt;
	}

	public void setXslt(final String xslt) {
		this.xslt = xslt;
	}

	public String getOutputEprParam() {
		return outputEprParam;
	}

	public void setOutputEprParam(final String outputEprParam) {
		this.outputEprParam = outputEprParam;
	}

	public String getDbProperty() {
		return dbProperty;
	}

	public void setDbProperty(final String dbProperty) {
		this.dbProperty = dbProperty;
	}

	public String getSqlForSize() {
		return sqlForSize;
	}

	public void setSqlForSize(final String sqlForSize) {
		this.sqlForSize = sqlForSize;
	}

}
