package eu.dnetlib.data.sts.mock.utility;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.net.URL;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import eu.dnetlib.common.utils.xml.xpath.XPathParser;
import eu.dnetlib.data.utility.download.DownloadServiceException;
import eu.dnetlib.data.utility.download.IDownloadService;
import eu.dnetlib.data.utility.download.utils.UrlUtils;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.enabling.tools.JaxwsServiceResolverImpl;
import eu.dnetlib.enabling.tools.ServiceResolver;

public class mockDownloadService implements IDownloadService {

	@Override
	public String downloadURL(String url) throws DownloadServiceException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public W3CEndpointReference downloadURLs(List<String> urls)
			throws DownloadServiceException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public W3CEndpointReference downloadURLsFromRS(W3CEndpointReference epr)
			throws DownloadServiceException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public W3CEndpointReference downloadURLsFromXML(W3CEndpointReference epr,
			String urlXPath) throws DownloadServiceException {
		
		try {
			final ServiceResolver serviceResolver = new JaxwsServiceResolverImpl();
			final String rsId = serviceResolver.getResourceIdentifier(epr);

			if (rsId == null)
				throw new InvalidParameterException(
				"The resultset id not extracted from EPR");

			final ResultSetService resultSetService = serviceResolver.getService(
					ResultSetService.class, epr);
			int rsNum = resultSetService.getNumberOfElements(rsId);
			List<String> results = resultSetService.getResult(rsId, 1, rsNum, "non-waiting");

			W3CEndpointReference rsEPR = resultSetService.createPushRS(70, 70);
			final String rsId2 = serviceResolver.getResourceIdentifier(rsEPR);

			Iterator<String> iter = results.iterator();
			List<String> list = new ArrayList<String>();

			while (iter.hasNext()) {
				String object = iter.next();
				XPathParser xPathParser = new XPathParser(object, false);
				String newObject = updateXML(xPathParser, urlXPath);

				if (newObject == null)
					newObject = object;
				list.add(newObject);
			}

			resultSetService.populateRS(rsId2, list);
			resultSetService.closeRS(rsId2);
			return rsEPR;
		} catch (Exception e) {
			throw new DownloadServiceException (e);
		}

	}

	@Override
	public String identify() {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	private String updateXML(XPathParser xPathParser, String urlXPath) 
		throws Exception {
		
		String fieldContent = xPathParser.getElementValue(urlXPath);		
	
		URL verifiedUrl = UrlUtils.verifyUrl(fieldContent);
		
		if (verifiedUrl != null) {
			
			String pathToWrite = "/tmp/"+fieldContent.hashCode();
			BufferedWriter out = new BufferedWriter(new FileWriter(pathToWrite));
			out.write("I am only mock and i " +
					"am storing here only url instead of downloaded " +
					"object :"+ fieldContent);
			out.close();
		
			int fieldIndexFrom = urlXPath.lastIndexOf("/");
			if (fieldIndexFrom == -1) {
				throw new Exception("Can not extract field name from XPath: "+urlXPath);
			}
			String fieldName = urlXPath.substring(fieldIndexFrom+1, urlXPath.length());

			String schema = null;
			if (fieldName.contains(":")) {
				int schemaIndexTo = fieldName.lastIndexOf(":");
				if (schemaIndexTo == -1) {
					throw new Exception("Can not extract schema from field: "+fieldName);
				}
				schema = fieldName.substring(0, schemaIndexTo);
			}

			HashMap<String, String> schemas = xPathParser.extractSchemas();
			//log.debug("Updating xml with an object downloading path");	
			xPathParser.updateElementValue(urlXPath,fieldName,pathToWrite, schema, schemas.get(schema));

			return xPathParser.getModifiedDocument();
		}
		else {
			return null;
		}	
		
	}

	@Override
	public W3CEndpointReference downloadURLsFromListXML(List<String> urls,
			String urlXPath) throws DownloadServiceException {
		try {
			final ServiceResolver serviceResolver = new JaxwsServiceResolverImpl();
			
			//TODO:put here proper RS mock
			JaxWsProxyFactoryBean factory0 = new JaxWsProxyFactoryBean();
			factory0.setServiceClass(ResultSetService.class);
			//factory0.setAddress(
			//		"http://146.48.85.160:8280/is/services/resultSet");
			factory0.setAddress(
					"http://129.70.40.103:8090/app/services/resultSet");
			ResultSetService resultSetService = (ResultSetService) factory0.create();
			
			W3CEndpointReference rsEPR = resultSetService.createPushRS(70, 70);
			final String rsId2 = serviceResolver.getResourceIdentifier(rsEPR);

			Iterator<String> iter = urls.iterator();
			List<String> list = new ArrayList<String>();

			while (iter.hasNext()) {
				String object = iter.next();
				XPathParser xPathParser = new XPathParser(object, false);
				String newObject = updateXML(xPathParser, urlXPath);

				if (newObject == null)
					newObject = object;
				list.add(newObject);
			}

			resultSetService.populateRS(rsId2, list);
			resultSetService.closeRS(rsId2);
			return rsEPR;
		} catch (Exception e) {
			throw new DownloadServiceException (e);
		}
	}
	
}
