package eu.dnetlib.enabling.aas.ismock;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import eu.dnetlib.common.rmi.UnimplementedException;
import eu.dnetlib.enabling.aas.is.ISConstants;
import eu.dnetlib.enabling.aas.utils.CommonUtils;
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;

/**
 * Mock class implementing ResultSet service functionalities.
 * @author mhorst
 *
 */
public class MockResultSet implements ResultSetService {

	Map <String,String[]> results = new HashMap<String, String[]>();
	
	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#closeRS(java.lang.String)
	 */
	public void closeRS(String rsId) {
		throw new UnimplementedException();
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPullRS(java.lang.String, java.lang.String, int, int, java.lang.String, java.lang.Integer, java.lang.Integer)
	 */
	public W3CEndpointReference createPullRS(String dataProviderServiceAddress,
			String bdId, int initialPageSize, int expiryTime,
			String styleSheet, Integer keepAliveTime, Integer total) {
		throw new UnimplementedException();
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#createPushRS(int, int)
	 */
	public W3CEndpointReference createPushRS(int expiryTime, int keepAliveTime) {
		throw new UnimplementedException();
	}

	/**
	 * This method was removed from interface.
	 * @param rsId
	 * @return
	 */
	public boolean deleteRS(String rsId) {
		if (rsId==null)
			return false;
		String[] removed = results.remove(rsId);
		if (removed!=null)
			return true;
		else
			return false;
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getNumberOfElements(java.lang.String)
	 */
	public int getNumberOfElements(String rsId) {
		if (rsId==null)
			return 0;
		String[] result = results.get(rsId);
		if (result==null)
			return 0;
		else
			return result.length;
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getRSStatus(java.lang.String)
	 */
	public String getRSStatus(String rsId) {
		return ISConstants.RESULT_SET_STATUS_CLOSED;
	}


	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.aas.isgen.resultset.ResultSet_portType#getResult(java.lang.String, int, int, java.lang.String, org.driver.schema.GetResultType)
	 */
	public List<String> getResult(String rsId, int fromPosition,
			int toPosition, String requestMode) {
//		only default requestMode and resultType are supported.
		if (rsId==null)
			return new ArrayList<String>(0);
//		adapting fromPosition offset
		fromPosition--;
		if (toPosition!=ISConstants.RESULT_SET_END_POSITION_UNSPECIFIED)
		toPosition--;
		
		String[] result = results.get(rsId);
		if (result==null ||	fromPosition > result.length)
			return new ArrayList<String>(0);
		
		if (fromPosition<0)
			fromPosition=0;
		
		if (toPosition==ISConstants.RESULT_SET_END_POSITION_UNSPECIFIED) {
			if (fromPosition==0) {
				return Arrays.asList(result);
			}else
				return Arrays.asList(getSubArray(result,fromPosition,result.length-1));
		} else {
			if (toPosition<fromPosition)
				return new ArrayList<String>(0);
			if (toPosition > result.length-1)
				toPosition = result.length-1;
			return Arrays.asList(getSubArray(result,fromPosition,toPosition));
		}
	}
	
	/**
	 * Returns subarray of array given as parameter.
	 * All params need to be previously validated. 
	 * @param srcArray
	 * @param fromPosition
	 * @param toPosition
	 * @return
	 */
	private String[] getSubArray(String[] srcArray, int fromPosition, int toPosition) {
		String[] resultArray = new String[toPosition-fromPosition+1];
		int counter=0;
		for (int i=fromPosition; i<=toPosition; i++) {
			resultArray[counter] = srcArray[i];
			counter++;
		}
		return resultArray;
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.common.rmi.BaseService#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 UnimplementedException();
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#populateRS(java.lang.String, java.util.List)
	 */
	public String populateRS(String rsId, List<String> elements) {
		if (rsId==null)
			return null;
		if (elements==null ||elements.size()==0)
			return rsId;
		String[] foundResult = results.get(rsId);
		if (foundResult==null)
			results.put(rsId, elements.toArray(new String[0]));
		else {
			String[] joinedTables = CommonUtils.joinStringTables(
					foundResult, elements.toArray(new String[0]));
			results.put(rsId, joinedTables);
		}
		return rsId;
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.common.rmi.BaseService#identify()
	 */
	public String identify() {
		return "ResultSet-mock-0.9.0";
	}

	/* (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)
	 */
	public W3CEndpointReference createPullRSEPR(
			W3CEndpointReference dataProviderEPR, String bdId,
			int initialPageSize, int expiryTime, String styleSheet,
			Integer keepAliveTime, Integer total) {
		throw new UnimplementedException();
	}

	/* (non-Javadoc)
	 * @see eu.dnetlib.enabling.resultset.rmi.ResultSetService#getProperty(java.lang.String, java.lang.String)
	 */
	public String getProperty(String rsId, String name)
			throws ResultSetException {
		throw new UnimplementedException();
	}

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

}
