package eu.dnetlib.enabling.ui.server;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

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

import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Required;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import eu.dnetlib.data.index.IIndexService;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.enabling.tools.ServiceResolver;
import eu.dnetlib.enabling.ui.common.services.IndexService;
import eu.dnetlib.enabling.ui.common.services.MyGwtException;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;

public class IndexServlet extends RemoteServiceServlet implements IndexService {
	private static final long serialVersionUID = -8554657170441123280L;

	private ServiceResolver serviceResolver;
	private SAXReader reader = new SAXReader();
	
	/**
	 * build epr.
	 */
	@Resource
	private StandaloneCxfEndpointReferenceBuilder eprBuilder;

	private String mdFormat;
	
	public IndexServlet() {
		super();
	}
	
	
	public ServiceResolver getServiceResolver() {
		return serviceResolver;
	}
	
	@Required
	public void setServiceResolver(ServiceResolver serviceResolver) {
		this.serviceResolver = serviceResolver;
	}
	
	
	public List<String> executeQueryCQL(String indexURL, String repoId, String cql) throws MyGwtException {
		List<String> res = new ArrayList<String>();

		String query = "";
		if ((repoId != null)&&(repoId.length() > 0)) {
			query = "(repositoryId=\"" + repoId + "\")";
		}
	
		if ((cql != null)&&(cql.length() > 0)) {
			if (query.length() > 0) query += " AND ";
			query += "(" + cql + ")";
		}

		if (query.length() == 0) {
			query = "CobjTypology=Textual";
		}	
		IIndexService index = getIndexStub(indexURL);
		
		if (index != null) {
			try {
				W3CEndpointReference epr = index.indexLookup("all", query, mdFormat, "index");
			
				ResultSetService resultset = serviceResolver.getService(ResultSetService.class, epr);
				String rsId = serviceResolver.getResourceIdentifier(epr);
				
				int total = resultset.getNumberOfElements(rsId);
				
				res.add("<b>Total of elements:</b> " + total);
				res.add("<hr />");
				if (total > 20) total = 20;
				for (String elem : resultset.getResult(rsId, 1, total, "WAITING")) {
					res.add(calculateResponseElement((reader.read(new StringReader(elem))).getRootElement()));
					res.add("<hr />");
				}
			} catch (Exception e) {
				res.add("<b>ERROR:</b> " + e.getMessage());
			}
		} else {
			res.add("<b>ERROR:</b> Invalid index");
		}
		
		return res;
	}

	
	private IIndexService getIndexStub(String address) {
		W3CEndpointReference epr = eprBuilder.getEndpointReference(address, null, null, address + "?wsdl", null, null);
		return serviceResolver.getService(IIndexService.class, epr);
	}
	
	
	
	private String calculateResponseElement(Element e) {
		String res = "";
		
		List<?> list = e.selectNodes("./*");
		
		if (list.isEmpty()) {
			res =  "<b>" + e.getName() + ":</b> " + e.getText() + "<br />";  
		} else {
			for (Object o : list) {
				res += calculateResponseElement((Element) o);
			}
		}
		return res;
	}

	
	public String getMdFormat() {
		return mdFormat;
	}

	@Required
	public void setMdFormat(String mdFormat) {
		this.mdFormat = mdFormat;
	}
	
}
