/**
 * Copyright © 2008-2009 DRIVER PROJECT (ICM UW)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.dnetlib.resultset.impl;

import java.util.List;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.log4j.Logger;

import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.resultset.api.IResultSet;

/**
 * This facade is required to bind {@link IndexResultSet} directly to the {@link IndexServiceFacade} 
 * without having to get round the SOAP transportation layer.
 * It encapsulates {@link IndexResultSet} instance;
 * TODO catch all Exceptions and convert them to GenericFaultMessage 
 * @author Marek Horst
 * @version 0.01
 *
 */
public class IndexResultSetFacade implements ResultSetService {

	protected static final Logger log = Logger.getLogger(IndexResultSetFacade.class);
	
	/**
	 * Embedded Index ResultSet module.
	 */
	private IResultSet indexResultSet;
	
	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#closeRS(java.lang.String)
	 */
	public void closeRS(String rsId) {
		try {
			indexResultSet.closeRS(rsId);
		} catch (IndexResultSetFaultMessage e) {
			log.error(e.getMessage());
		}
	}
	
	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#createPullRS(java.lang.String, java.lang.String, int, int, org.driver.resultset.CreatePullRSType)
	 */
	public W3CEndpointReference createPullRS(String dataProviderServiceAddress, String bdId,
			int initialPageSize, int expiryTime,String styleSheet, 
			Integer keepAliveTime, Integer total) {
		
		eu.dnetlib.resultset.impl.CreatePullRSType internalCreatePullRS_type = null;
		internalCreatePullRS_type = new eu.dnetlib.resultset.impl.CreatePullRSType();
		internalCreatePullRS_type.setKeepAliveTime(keepAliveTime);
		internalCreatePullRS_type.setStyleSheet(styleSheet);
		internalCreatePullRS_type.setTotal(total);
		
			
		try {
			return indexResultSet.createPullRS(dataProviderServiceAddress, bdId, 
						initialPageSize, expiryTime, internalCreatePullRS_type);
		} catch (IndexResultSetFaultMessage e) {
			log.error(e.getMessage());
			return null;
		}
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#createPushRS(int, org.driver.resultset.CreatePushRSType)
	 */
	public W3CEndpointReference createPushRS(int expiryTime, CreatePushRSType createPushRSType)
			throws IndexResultSetFaultMessage {
		eu.dnetlib.resultset.impl.CreatePushRSType internalCreatePushRS_type = null;
		if (createPushRSType!=null) {
			internalCreatePushRS_type = new eu.dnetlib.resultset.impl.CreatePushRSType();
			internalCreatePushRS_type.setKeepAliveTime(createPushRSType.getKeepAliveTime());
		}
		
		return indexResultSet.createPushRS(expiryTime, internalCreatePushRS_type);
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#deleteRS(java.lang.String)
	 */
	public boolean deleteRS(String rsId) throws IndexResultSetFaultMessage {
		
		return indexResultSet.deleteRS(rsId);
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#fusion(int, org.driver.resultset.Array1)
	 */
	public String fusion(int expiryTime, Array1 eprs)
			throws IndexResultSetFaultMessage {
		eu.dnetlib.resultset.impl.Array1 internalEprs = null;
		if (eprs!=null && eprs.getElement()!=null) {
			internalEprs = new Array1Ext(eprs.getElement().toArray(
					new String[eprs.getElement().size()]));
		}
		
		return indexResultSet.fusion(expiryTime, internalEprs);
		
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#getBulkData(java.lang.String, int, int)
	 */
	public Array1 getBulkData(String bdId, int fromPosition, int toPosition) {
		throw new RuntimeException("This method is unsupported in Index ResultSet implementation!");
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#getNumberOfElements(java.lang.String)
	 */
	public int getNumberOfElements(String rsId) {
		try {
			return indexResultSet.getNumberOfElements(rsId);
		} catch (IndexResultSetFaultMessage e) {
			log.error(e.getMessage());
			return 0;
		}
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#getNumberOfResults(java.lang.String)
	 */
	public String getNumberOfResults(String bdId) throws IndexResultSetFaultMessage {
		
		log.info("FReceived rsId: " + bdId);
		return indexResultSet.getNumberOfResults(bdId);	
	}
	
	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#getNumberOfResultsGettingBulkData(java.lang.String, int, int)
	 */
	public Array1 getNumberOfResultsGettingBulkData(String bdId,
			int fromPosition, int toPosition) {
		throw new RuntimeException("This method is unsupported in Index ResultSet implementation!");
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#getProperty(java.lang.String, java.lang.String)
	 */
	public String getProperty(String rsId, String name){
		
		try {
			return indexResultSet.getProperty(rsId, name);
		} catch (IndexResultSetFaultMessage e) {
			log.error(e.getMessage());
			return null;
		}
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#getRSStatus(java.lang.String)
	 */
	public String getRSStatus(String rsId) {
		try {
			return indexResultSet.getRSStatus(rsId);
		} catch (IndexResultSetFaultMessage e) {
			log.error(e.getMessage());
			return null;
		}	
	}
		
	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#identify()
	 */
	public String identify() {
		return indexResultSet.identify();
	}


	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#notify(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	public void notify(String subscrId, String topic, String isId,
			String message) {
		throw new RuntimeException("This method is unsupported in Index ResultSet implementation!");
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#preparePullRS(java.lang.String, int, int, org.driver.resultset.PreparePullRSType)
	 */
	public String preparePullRS(String dataProviderServiceAddress,
			int initialPageSize, int expiryTime,
			PreparePullRSType preparePullRSType) throws IndexResultSetFaultMessage {
		eu.dnetlib.resultset.impl.PreparePullRSType internalPreparePullRS_type = null;
		if (preparePullRSType!=null) {
			internalPreparePullRS_type = new eu.dnetlib.resultset.impl.PreparePullRSType();
			internalPreparePullRS_type.setKeepAliveTime(preparePullRSType.getKeepAliveTime());
			internalPreparePullRS_type.setStyleSheet(preparePullRSType.getStyleSheet());
			internalPreparePullRS_type.setTotal(preparePullRSType.getTotal());
		}

			return indexResultSet.preparePullRS(dataProviderServiceAddress, initialPageSize, 
					expiryTime, internalPreparePullRS_type);
		
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#rSasResource(java.lang.String, java.lang.String)
	 */
	public String rSasResource(String rsId, String label)
			throws IndexResultSetFaultMessage {
			return indexResultSet.rSasResource(rsId, label);
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#refreshExpiryTime(java.lang.String, int)
	 */
	public boolean refreshExpiryTime(String rsId, int expiryTime)
			throws IndexResultSetFaultMessage {
			return indexResultSet.refreshExpiryTime(rsId, expiryTime);
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#removeProperty(java.lang.String, java.lang.String)
	 */
	public String removeProperty(String rsId, String name){
		throw new RuntimeException("This method is unsupported in Index ResultSet implementation!");
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#removeResult(java.lang.String, int)
	 */
	public String removeResult(String rsId, int position)
			throws IndexResultSetFaultMessage {
			return indexResultSet.removeResult(rsId, position);
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#setProperty(java.lang.String, java.lang.String, java.lang.String)
	 */
	public String setProperty(String rsId, String name, String value){
		throw new RuntimeException("This method is unsupported in Index ResultSet implementation!");
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#simpleGetResult(java.lang.String, int, int, java.lang.String)
	 */
	public String[] simpleGetResult(String rsId, int fromPosition,
			int toPosition, String requestMode) throws IndexResultSetFaultMessage {
		String[] internalResult;
			internalResult = indexResultSet.simpleGetResult(
					rsId, fromPosition, toPosition, requestMode);
			return internalResult;
	}

	/* (non-Javadoc)
	 * @see org.driver.resultset.ResultSetPortType#startPullRS(java.lang.String, java.lang.String, int, org.driver.resultset.StartPullRSType)
	 */
	public String startPullRS(String rsId, String bdId, int expiryTime,
			StartPullRSType startPullRSType) throws IndexResultSetFaultMessage {
		eu.dnetlib.resultset.impl.StartPullRSType internalStartPullRS_type = null;
		if (startPullRSType!=null) {
			internalStartPullRS_type = new eu.dnetlib.resultset.impl.StartPullRSType();
			internalStartPullRS_type.setKeepAliveTime(startPullRSType.getKeepAliveTime());
			internalStartPullRS_type.setStyleSheet(startPullRSType.getStyleSheet());
			internalStartPullRS_type.setTotal(startPullRSType.getTotal());
		}
		return indexResultSet.startPullRS(rsId, bdId, expiryTime, internalStartPullRS_type);
	}

	/**
	 * Returs Embedded Index ResultSet module.
	 * @return Embedded Index ResultSet module
	 */
	public IResultSet getIndexResultSet() {
		return indexResultSet;
	}

	/**
	 * Sets Embedded Index ResultSet module.
	 * @param indexResultSet
	 */
	public void setIndexResultSet(IResultSet indexResultSet) {
		this.indexResultSet = indexResultSet;
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPullRSEPR(javax.xml.ws.wsaddressing.W3CEndpointReference, java.lang.String, int, int, java.lang.String, java.lang.Integer, java.lang.Integer)
	 */
	@Override
	public W3CEndpointReference createPullRSEPR(
			W3CEndpointReference dataProviderEPR, String bdId,
			int initialPageSize, int expiryTime, String styleSheet,
			Integer keepAliveTime, Integer total) {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPushRS(int, int)
	 */
	
	public W3CEndpointReference createPushRS(int expiryTime, int keepAliveTime)
			throws ResultSetException {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getResult(java.lang.String, int, int, java.lang.String)
	 */

	public List<String> getResult(String rsId, int fromPosition,
			int toPosition, String requestMode) throws ResultSetException {
		try {
			return indexResultSet.getResult(
					rsId, fromPosition, toPosition, requestMode, null);
		} catch (IndexResultSetFaultMessage e) {
			throw new ResultSetException(e);
		}
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.common.rmi.BaseService#start()
	 */

	public void start() {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#populateRS(java.lang.String, java.util.List)
	 */
	public String populateRS(String rsId, List<String> elements)
			throws ResultSetException {
		
		eu.dnetlib.resultset.impl.Array1 internalElements = null;
		if (elements!=null && !elements.isEmpty()) {
			internalElements = new Array1Ext(elements.toArray(
				new String[elements.size()]));
		} else {
			internalElements = new Array1Ext(new String[0]);
		}
		try {
			return indexResultSet.populateRS(rsId, elements);
		} catch (IndexResultSetFaultMessage e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage());
			throw new ResultSetException(e.getMessage());
		}

	}

}
