/**
 * 
 */
package eu.dnetlib.data.utility.featureextraction.nh;

import java.io.StringReader;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.xml.sax.InputSource;

import eu.dnetlib.common.interfaces.nh.IBlackboardMessage.Action;
import eu.dnetlib.data.utility.featureextraction.Feature;
import eu.dnetlib.data.utility.featureextraction.FeatureExtractionException;
import eu.dnetlib.data.utility.featureextraction.FeatureExtractionServiceParameters;
import eu.dnetlib.data.utility.featureextraction.Feature.STORAGETYPE;
import eu.dnetlib.data.utility.featureextraction.dataprovider.FeatureExtractionDataProvider;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.enabling.tools.blackboard.AbstractBlackboardNotificationHandler;
import eu.dnetlib.enabling.tools.blackboard.BlackboardJob;
import eu.dnetlib.enabling.tools.blackboard.BlackboardServerHandler;
import eu.dnetlib.resultset.impl.builder.IResultSetBuilder;

/**
 * @author jochen
 *setResultsetService
 */
public class FeatureExtractionNotificationHandler extends AbstractBlackboardNotificationHandler<BlackboardServerHandler>{

	private FeatureExtractionDataProvider dataProvider;
	private ResultSetService resultsetService;

	/** Result Set service location. */
	private String resultSetLocation;
	
	private IResultSetBuilder resultSetBuilder;
	
	/**
	 * Inits the.
	 */
	public void init() {
		this.resultsetService = resultSetBuilder.build(resultSetLocation);
	}
	
	@Override
	protected void processJob(BlackboardJob job) {
		try{
			Action action = Action.valueOf(Action.class, job.getAction());
			if (!(  (action == Action.CANCEL) || 
					(action == Action.EXTRACT)	)){
				job.setError("unsupported Action: " + job.getAction());
				throw new FeatureExtractionException("unsupported message action: " + job.getAction());
			}
			if (job.getParameters().get(FeatureExtractionServiceParameters.PARAM_NAME_FEATURE) == null)
				throw new FeatureExtractionException("Wrong parameter! 'feature' can not be null!");
			if ( !this.dataProvider.getFeatureMap().containsKey(job.getParameters().get(FeatureExtractionServiceParameters.PARAM_NAME_FEATURE))){
				throw new FeatureExtractionException("unsupported feature: " + job.getParameters().get(FeatureExtractionServiceParameters.PARAM_NAME_FEATURE));
			}
			if (job.getParameters().get(FeatureExtractionServiceParameters.PARAM_NAME_SOURCE_RESULTSETSERVICE_EPR) == null)
				throw new FeatureExtractionException("Wrong parameter! 'src_rs_epr' can not be null!");

			InputSource eprSource = new InputSource(new StringReader(job.getParameters().get(FeatureExtractionServiceParameters.PARAM_NAME_SOURCE_RESULTSETSERVICE_EPR)));
			W3CEndpointReference srcRsEpr = new W3CEndpointReference(new DOMSource(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(eprSource)));

			TaskListener listener = new TaskListener();
			listener.setJobMessage(job);
			listener.setJobMessageHandler(getBlackboardHandler());
			Feature feature = new Feature();
			feature.setName(job.getParameters().get(FeatureExtractionServiceParameters.PARAM_NAME_FEATURE));
			if (job.getParameters().containsKey(FeatureExtractionServiceParameters.PARAM_NAME_STORAGETYPE)){
				if (job.getParameters().get(FeatureExtractionServiceParameters.PARAM_NAME_STORAGETYPE).equals(Feature.STORAGETYPE.INCREMENTAL.name())){
					feature.setStorageType(STORAGETYPE.INCREMENTAL);
				}
			}
			W3CEndpointReference sinkRsEpr = dataProvider.createResultSet(feature, srcRsEpr, resultsetService, listener);
			job.getParameters().put(FeatureExtractionServiceParameters.PARAM_NAME_SINK_RESULTSETSERVICE_EPR, sinkRsEpr.toString());
			
			getBlackboardHandler().ongoing(job);

		}catch(final Throwable e){
			getBlackboardHandler().failed(job, e);
		}
		
		
	}

	public FeatureExtractionDataProvider getDataProvider() {
		return dataProvider;
	}

	public void setDataProvider(FeatureExtractionDataProvider dataProvider) {
		this.dataProvider = dataProvider;
	}
	
	/**
	 * Returns ResultSet builder module.
	 * @return ResultSet builder module
	 */
	public IResultSetBuilder getResultSetBuilder() {
		return resultSetBuilder;
	}

	/**
	 * Sets ResultSet builder module.
	 * @param resultSetBuilder
	 */
	public void setResultSetBuilder(IResultSetBuilder resultSetBuilder) {
		this.resultSetBuilder = resultSetBuilder;
	}
	
	/**
	 * Returns target Result Set service location.
	 * 
	 * @return target Result Set service location
	 */
	public String getResultSetLocation() {
		return resultSetLocation;
	}

	/**
	 * Sets target Result Set service location.
	 * 
	 * @param resultSetLocation
	 */
	public void setResultSetLocation(String resultSetLocation) {
		this.resultSetLocation = resultSetLocation;
	}
	
	public ResultSetService getResultsetService() {
		return resultsetService;
	}

	public void setResultsetService(ResultSetService resultsetService) {
		this.resultsetService = resultsetService;
	}

}
