/**
 * Copyright 2008-2009 DRIVER PROJECT (ICM UW)
 * Original author: Marek Horst
 *
 * 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.enabling.manager;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.xml.ws.soap.SOAPFaultException;
import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.log4j.Logger;

import sun.misc.BASE64Encoder;
import eu.dnetlib.common.utils.xml.xpath.XPathParser;
import eu.dnetlib.data.index.IIndexService;
import eu.dnetlib.data.index.IndexServiceException;
import eu.dnetlib.data.mdstore.IMDStoreService;
import eu.dnetlib.data.mdstore.MDStoreServiceException;
import eu.dnetlib.data.sts.das.IDataAccessService;
import eu.dnetlib.data.sts.ds.IDepotService;
import eu.dnetlib.data.utility.featureextraction.Feature;
import eu.dnetlib.data.utility.featureextraction.IFeatureExtractionService;
import eu.dnetlib.data.utility.featureextraction.Feature.STORAGETYPE;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.is.registry.ISRegistryDocumentNotFoundException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.manager.rs.iterator.ResultSetFeedIteratorOld;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.enabling.tools.JaxwsServiceResolverImpl;
import eu.dnetlib.enabling.tools.ServiceResolver;
import eu.dnetlib.miscutils.datetime.DateUtils;


// TODO: Auto-generated Javadoc
/**
 * The Class DManagerServiceFacade.
 */
public class DManagerServiceFacadeOld {

	/** The Constant log. */
	protected static final Logger log = Logger.getLogger(DManagerServiceFacadeOld.class);

	/** IS-LU service. */
	private ISLookUpService lookUpService;

	/** Result Set service. */
	private transient ResultSetService resultSetService;
	
	/** IS Registry service. */
	private ISRegistryService registryService;
	
	private IDepotService depotService;
	
	private IDataAccessService dataAccessService;
	
	private IMDStoreService mdstoreService;
	
	private IFeatureExtractionService fesService;
	
	private IIndexService indexService;
	
	/** Current Store service version. */
	private String serviceVersion;
	
	/** Storing Iterator queue size. */
	private int rsQueueSize;

	/** Storing Iterator single call result size. */
	private int rsPackageSize;

	/** Maximum timeout (in seconds) for retrieving single result from ResultSet while storing records. */
	long maxRSIteratorTimeout;
	
	/** The rs closing timeout. */
	private int rsClosingTimeout;
	
	/** The expiry time. */
	private int expiryTime;
	
	/** The keep alive time. */
	private int keepAliveTime;
	
	private String storeBackendAddress;

	private InfoFile infoFile;
	
	public String identify() {
		return getServiceVersion();
	}
	
	public void processFullText (String repositoryName) throws Exception {
		checkServices();
		downloadAndStore(repositoryName);
		extractAndStore(repositoryName);
		index(repositoryName);
	}
	
	
	public void processStandardIndexing (String repositoryName) throws Exception {
		checkServices();
		
		String mdstoreId = this.getDMFMDStoreIdentifier(
				this.getRepositoryIdentifier(repositoryName));
		
		updateMDStoreProfile(this.getDMFMDStoreProfile(mdstoreId), mdstoreId);
	}
	
	
	public void downloadAndStore (String repositoryName) throws Exception {
		checkServices();
		String repoId = this.getRepositoryIdentifier(repositoryName);
		infoFile = new InfoFile(repoId);	
		String mdstoreId = this.getDMFMDStoreIdentifier(repoId);
		infoFile.write("mdstoreid", mdstoreId);
		W3CEndpointReference mdstoreEPR = deliverMDRecords(mdstoreId);
		ResultSetFeedIteratorOld DMFIter = initResultSetIterator(mdstoreEPR,"store");
		String stds = infoFile.get("storeidforextraction");
		
		if (stds == null || "".equals(stds)) {
			stds = createStoreDataStructure();
			infoFile.write("storeidforextraction", stds);
		}
		
		W3CEndpointReference storeObjectsRsEPR = processRecords(DMFIter);
		storeObjects(storeObjectsRsEPR, stds);
	}
	
	public void extractAndStore (String repositoryName) throws Exception {
		checkServices();
		String repoId = this.getRepositoryIdentifier(repositoryName);
		infoFile = new InfoFile(repoId);
		String stdsRead = infoFile.get("storeidforextraction");
		if (stdsRead == null || "".equals(stdsRead)) {
			String excp = "Can not find Store Data Structure Id where the original full-texts are" +
					"stored. Field 'storeidforextraction' in repository InfoFile seems to be empty";
			log.error(excp);
			throw new Exception(excp);
		}
		
		String stdsWrite = infoFile.get("storeidforextractedft");
		if (stdsWrite == null || "".equals(stdsWrite)) {
			stdsWrite = createStoreDataStructure();
			infoFile.write("storeidforextractedft", stdsWrite);
		}
		
		W3CEndpointReference fesEPR = extraction(stdsRead,stdsWrite);
		log.debug("Received FES EPR" + fesEPR);
		
	}
	
	public void index (String repositoryName) throws Exception {
		checkServices();
		String repoId = this.getRepositoryIdentifier(repositoryName);
		infoFile = new InfoFile(repoId);	
		
		String stdsRead = infoFile.get("storeidforextractedft");
		if (stdsRead == null || "".equals(stdsRead)) {
			String excp = "Can not find Store Data Structure Id where the extracted full-texts are" +
					"stored. Field 'storeidforextractedft' in repository InfoFile seems to be empty";
			log.error(excp);
			throw new Exception(excp);
		}
		log.debug("Found Store Data Structure Identifier: "+ stdsRead);
		log.debug("Requesting Data Access Service for SDOs");
		
		W3CEndpointReference dasEPR = dataAccessService.storeLookUpSDORS(stdsRead);
		log.debug("RSEPR received from Store DAS Service:"+ dasEPR);
		
		ResultSetFeedIteratorOld SDOIter = initResultSetIterator(dasEPR,"indexfromsdo");
		
		log.debug("Processing ResultSet with text records extracted by FES");
		W3CEndpointReference indexObjectsRsEPR = processRecords(SDOIter);
		log.debug("Got ResultSet EPR containing index records: "+ indexObjectsRsEPR);
		
		String indexId = infoFile.get("indexid");
		if (indexId == null || "".equals(indexId)) {
			String mdstoreId = infoFile.get("mdstoreid");
			if (mdstoreId == null || "".equals(mdstoreId)) {
				String excp = "Can not find MDStore Id." +
						"Field 'mdstoreid' in repository InfoFile seems to be empty";
				log.error(excp);
				throw new Exception(excp);
			}
			indexId = getIndexIdentifier(mdstoreId);
			infoFile.write("indexid", indexId);
		}
		
		if (indexId != null && indexObjectsRsEPR != null) {
			log.debug("Found Index Identifier: "+ indexId);
		
			//Thread.sleep(60000);//FES gives the resultset back in the same time when the results are 
			//stored in Stores Service. The resultSet contains link records in this point of time but they are not yet
			//stored in Store Service so the index can not download them SHOULD BE NOTIFIED WHEN THE STORE SERVICE PROFILE DATE IS MODIFIED
			log.debug("Initiaiting Full-text indexing process");
			feedFullText(indexObjectsRsEPR,indexId);
		} else {
			String excp = "Either index identifier or ResultSet EPR are empty. Can not start indexing";
			log.error(excp);
			throw new Exception(excp);
		}
	}
	
	

	private String getIndexIdentifier (String mdstoreId) throws Exception {
		String indexId = null;

		try {
			List<String> indexIds = lookUpService.quickSearchProfile(
					"for $el in fn:collection("+
					"\"DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType\")"+
					" return ($el)//INDEX_MAP/INDEX[MDSTORE/@id=\""+mdstoreId+"\"]/data(@id)");

			if (indexIds != null && indexIds.size() != 0) {			
				indexId = indexIds.get(0);
				log.info("Index identifier returned by IS: "+ indexId);
				return indexId;
			} else {
				String msg = "Could not get Index id from IS: "+
				"for $el in fn:collection("+
				"\"DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType\")"+
				"return ($el)//INDEX_MAP/INDEX[MDSTORE/@id=\""+mdstoreId+"\"]/data(@id)";
				log.error(msg);
				throw new Exception(msg);
			}
		} catch(ISLookUpException e) {
			log.error(e);
			throw new Exception(e);
		}
	}

	private void feedFullText(W3CEndpointReference indexEPR, String ixId) throws IndexServiceException {
		
		BASE64Encoder encoder = new BASE64Encoder();
		String indexEPR64Enc = encoder.encode(indexEPR.toString().getBytes());
		
		indexService.feedIndex(ixId,"INCREMENTAL", indexEPR64Enc, true, true);
		
	}

	private void checkServices() throws Exception{
			
		try {
			log.info("Store Depot Service identified: " + depotService.identify() );
		} catch (Exception e) {
			throw new Exception ("Problem with Store Depot Service identification: "+ e);
		}	
		
		try {
			log.info("Store Data Access Service identified: " + dataAccessService.identify() );
		} catch (Exception e) {
			throw new Exception ("Problem with Store Data Access Service identification: "+ e);
		}	
		
		try {
			log.info("Feature Extraction Service identified: " + fesService.identify() );
		} catch (Exception e) {
			throw new Exception ("Problem with Feature Extraction Service identification: "+ e);
		}		
			
		try {
			log.info("MDStore Service identified: " + mdstoreService.identify() );
		} catch (Exception e) {
			throw new Exception ("Problem with MDStore Service identification: "+ e);
		}		
			
		try {
			//log.info("Index Service identified: " + indexService.identify() );
			log.info("ResultSET Service:" + resultSetService.identify());
		} catch (Exception e) {
			throw new Exception ("Problem with ResultSET Service identification: "+ e);
		}		
			
	}

	private W3CEndpointReference extraction(String stdsRead, String stdsWrite) throws Exception {
				
		try { 
			log.debug("Requesting Data Access Service for SDOs");
			W3CEndpointReference dasEPR = dataAccessService.storeLookUpSDORS(stdsRead);
			log.debug("RSEPR received from Store DAS Service:"+ dasEPR);
			log.debug("Sending request with DAS RS to FES");
			Feature f = new Feature();
			f.setName("fulltext");
			f.setStorageType(STORAGETYPE.INCREMENTAL);
			return fesService.extract(f, dasEPR, stdsWrite);
						
		} catch (Exception e) {
			log.error(e);
			throw new Exception(e);
		}
	}

	private W3CEndpointReference processRecords(ResultSetFeedIteratorOld resultsetIter) throws Exception {
		
		try {
			Iterator<String> iter = resultsetIter.iterate();
			
			//log.debug("Timing:"+ expiryTime + " - "+ keepAliveTime);
			W3CEndpointReference epr = 
				resultSetService.createPushRS(expiryTime, keepAliveTime);
			log.debug("New PushRS created: "+ epr);
			
			final ServiceResolver serviceResolver = new JaxwsServiceResolverImpl();
			final String rsId = serviceResolver.getResourceIdentifier(epr);
			
			int counter = 0;
			List<String> list = new ArrayList<String>();
			boolean send = false;
			
			while (iter.hasNext() && !send) {
				String object = iter.next();
				
				if (object.contains("ignorethisobject")) {
					log.debug("!!!!!!! Ignoring object resultset itterator object:" + object + "!!!!!!!" );
					continue;
				}
				
				if (counter<500) {
					list.add(object);
					counter++;
					log.debug(counter + "::: "+ object);
					send = false;
				} else {
					log.debug("Populating RS !!!");
					resultSetService.populateRS(rsId, list );
					list = new ArrayList<String>();
					counter = 0;
					send = true;
				}	
			}
			log.debug("EXit from loop");
			if (!send && list.size() != 0)
				resultSetService.populateRS(rsId,list);
			
			resultSetService.closeRS(rsId);
			int num = resultSetService.getNumberOfElements(rsId);
			log.debug("RS closed and ready for use, it contains now: "+ num );
			
			if (num == 0)
				throw new Exception ("No records in ResultSet");
			return epr;
			
		} catch (Exception e) {
			StringWriter sw = new StringWriter();
	        PrintWriter pw = new PrintWriter(sw, true);
	        e.printStackTrace(pw);
	        pw.flush();
	        sw.flush();
			log.error(sw.toString());
			throw new Exception(e);
		}
			
		
	}
	
	private void storeObjects (W3CEndpointReference epr, String stds) throws Exception{
		try {
			
			log.debug("Sending to the Store Service!");
			String actionId = depotService.storeObjectsFromRS(stds, epr, "REFRESH");
			log.debug("ACTION ID:" + actionId);
			
			boolean ongoing = true;
			while (ongoing) {
				log.debug("Waiting as long as the Store Service will be ready!");
				String storingProfile  = depotService.storingCallback(stds, actionId, false);
				log.debug(storingProfile);
				if (storingProfile.contains("NONACTIVE")) {
					ongoing = false;
					log.debug("STORING DONE");
				}
				//} else if (storingProfile.contains("FAILURE"))
				//	log.error("FAILURE: Exception during storing!");
				else
					Thread.sleep(20000);
				
			}	
		} catch (Exception e){
			throw new Exception(e);
		}
		
	}

	private String getRepositoryIdentifier (String repositoryName) throws Exception {
		String repositoryIdentifier = null;
		log.info("LookUp for repository Id of "+ repositoryName);
		
		try {
			List<String> repositoryIds = lookUpService.quickSearchProfile(
					"for $x in collection(" +
					"\"/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType\")" +
					" where $x/RESOURCE_PROFILE//OFFICIAL_NAME eq " +
					"\""+repositoryName+"\" return $x/RESOURCE_PROFILE//RESOURCE_IDENTIFIER");
			
			if (repositoryIds != null && repositoryIds.size() != 0) {			
				repositoryIdentifier = repositoryIds.get(0);
				repositoryIdentifier = repositoryIdentifier.replace("<RESOURCE_IDENTIFIER value=\"", "");
				repositoryIdentifier = repositoryIdentifier.replace("\"/>", "");
				log.info("Repository identifier returned by IS : "+ repositoryIdentifier);
				return repositoryIdentifier;
			} else {
				String msg = "Could not get repository id from IS: "+"for $x in collection(" +
				"\"/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType\")" +
				" where $x/RESOURCE_PROFILE//OFFICIAL_NAME eq " +
				"\""+repositoryName+"\" return $x/RESOURCE_PROFILE//RESOURCE_IDENTIFIER";
				log.error(msg);
				throw new Exception(msg);
			}
		} catch(ISLookUpException e) {
			throw new Exception(e);
		}
		
	}
	
	private String getDMFMDStoreIdentifier (String repositoryId) throws Exception {
		String mdstoreId = null;

		try {
			List<String> mdstoreIds = lookUpService.quickSearchProfile(
					"for $x in collection(" +
					"\"/db/DRIVER/TransformationDSResources/TransformationDSResourceType\")" +
					" where $x/RESOURCE_PROFILE//REPOSITORY_SERVICE_IDENTIFIER eq " +
					"\""+repositoryId+"\" return $x/RESOURCE_PROFILE//DATA_SINK");

			if (mdstoreIds != null && mdstoreIds.size() != 0) {			
				mdstoreId = mdstoreIds.get(0);
				mdstoreId = mdstoreId.replace("<DATA_SINK>dnet://MDStoreDS/", "");
				mdstoreId = mdstoreId.replace("?type=REFRESH</DATA_SINK>", "");
				log.info("MDStore identifier returned by IS: "+ mdstoreId);
				return mdstoreId;
			} else {
				String msg = "Could not get mdstore id from IS: "+"for $x in collection(" +
				"\"/db/DRIVER/TransformationDSResources/TransformationDSResourceType\")" +
				" where $x/RESOURCE_PROFILE//REPOSITORY_SERVICE_IDENTIFIER eq " +
				"\""+repositoryId+"\" return $x/RESOURCE_PROFILE//DATA_SINK";
				log.error(msg);
				throw new Exception(msg);
			}
		} catch(ISLookUpException e) {
			log.error(e);
			throw new Exception(e);
		}
	}
	
	private String getDMFMDStoreProfile (String mdstoreId) throws Exception {

		try {
			log.debug("IS identify:" + lookUpService.identify());
			String mdstoreProfile = lookUpService.getResourceProfile(mdstoreId);
			
			//log.debug("MDStore Profile:" + mdstoreProfile);
			if (mdstoreProfile != null && !"".equals(mdstoreProfile)) {			
				return mdstoreProfile;
			} else {
				String msg = "Could not get mdstore profile from IS";
				log.error(msg);
				throw new Exception(msg);
			}
		} catch(ISLookUpException e) {
			log.error("Exception: " + e);
			throw new Exception(e);
		}  catch(Exception e) {
			log.error("Exception: " + e);
			throw new Exception(e);
		}
	}
	
	private void updateMDStoreProfile (String mdstoreProfile, String mdstoreId) throws Exception {

		try {
			log.debug("IS identify:" + lookUpService.identify());
			
			DateUtils date = new DateUtils();
			
			XPathParser xPathParser = new XPathParser(mdstoreProfile, false);
			
			xPathParser.updateElementValue("//LAST_STORAGE_DATE", "LAST_STORAGE_DATE", date.getDateAsISO8601String(), null, null);
			mdstoreProfile = xPathParser.getModifiedDocument();
			
			log.debug("Updating MDStore profile in IS: " + mdstoreProfile);
			registryService.updateProfile(mdstoreId, mdstoreProfile,
					"MDStoreDSResourceType");
		 
			
			/*if (mdstoreProfile != null && !"".equals(mdstoreProfile)) {			
				return mdstoreProfile;
			} else {
				String msg = "Could not get mdstore profile from IS";
				log.error(msg);
				throw new Exception(msg);
			}
			*/
		} catch(ISLookUpException e) {
			log.error("Exception: " + e);
			throw new Exception(e);
		} catch (ISRegistryDocumentNotFoundException e) {
			String errorContent = "Exception occured when " +
			"updating MDStore profile in IS. Profile not found. ";	 
			log.error(errorContent + e);	
		} catch (ISRegistryException e) {
			String errorContent = "Exception occured when " +
				"updating MDStore profile from IS ";	 
			log.error(errorContent + e);
			throw new Exception(errorContent + e);		
		} catch (SOAPFaultException e) {
			String errorContent = "Exception occured when " +
				"updating MDStore profile in IS ";
			log.error(errorContent + e);
			throw new Exception(errorContent + e);	
		} catch(Exception e) {
			String errorContent = "Exception occured when " +
				"updating MDStore profile in IS ";
			log.error(errorContent + e);
			throw new Exception(errorContent + e);	
		}
	}
	/*
	private String getIndexIdentifier (String mdstoreId) throws Exception {
		String indexId = null;

		try {
			List<String> indexIds = lookUpService.quickSearchProfile(
					"for $x in collection(" +
					"\"/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType\")" +
					" where $x/RESOURCE_PROFILE//INDEX/MDSTORE[@id=" +
					"\""+mdstoreId+"\"] return $x/RESOURCE_PROFILE//INDEX");

			if (mdstoreIds != null && mdstoreIds.size() != 0) {			
				mdstoreId = mdstoreIds.get(0);
				mdstoreId = mdstoreId.replace("<DATA_SINK>dnet://MDStoreDS/", "");
				mdstoreId = mdstoreId.replace("?type=REFRESH</DATA_SINK>", "");
				log.info("MDStore identifier returned by IS: "+ mdstoreId);
				return mdstoreId;
			} else {
				String msg = "Could not get mdstore id from IS: "+"for $x in collection(" +
				"\"/db/DRIVER/TransformationDSResources/TransformationDSResourceType\")" +
				" where $x/RESOURCE_PROFILE//REPOSITORY_SERVICE_IDENTIFIER eq " +
				"\""+repositoryId+"\" return $x/RESOURCE_PROFILE//DATA_SINK";
				log.error(msg);
				throw new Exception(msg);
			}
		} catch(ISLookUpException e) {
			log.error(e);
			throw new Exception(e);
		}
	}
	*/
	
	private W3CEndpointReference deliverMDRecords(String mdstoreId) throws Exception{
		
		try {
			W3CEndpointReference mdstoreEPR = 
				mdstoreService.deliverMDRecords(mdstoreId, null, null, "valid", false);
			return mdstoreEPR;
		} catch (MDStoreServiceException e) {
			log.error(e);
			throw new Exception(e);
		}
		
	}
	
	private ResultSetFeedIteratorOld initResultSetIterator (W3CEndpointReference epr, String objectTypes) throws Exception {
			
			final ServiceResolver serviceResolver = new JaxwsServiceResolverImpl();
			final ResultSetService resultSetService = serviceResolver.getService(
					ResultSetService.class, epr);
			final String rsId = serviceResolver.getResourceIdentifier(epr);
			
			int DMFnumber = resultSetService.getNumberOfElements(rsId);
			log.debug("Number of objects:" + DMFnumber);
			
			ResultSetFeedIteratorOld rsIterator = new ResultSetFeedIteratorOld(
					this.rsQueueSize, this.rsPackageSize, 
					this.maxRSIteratorTimeout, resultSetService, rsId, this.rsClosingTimeout,
					objectTypes, storeBackendAddress);
			return rsIterator;
	}
	
	private String createStoreDataStructure () throws Exception {
		
		try { 
			return 	depotService.createStore(null, 0);
		} catch (Exception e) {
			log.error(e);
			throw new Exception(e);
		}
	}
	
	/**
	 * Returns IS-LU service.
	 * 
	 * @return IS-LU service
	 */
	public ISLookUpService getLookUpService() {
		return lookUpService;
	}

	/**
	 * Sets IS-LU service.
	 * 
	 * @param lookUpService the look up service
	 */
	public void setLookUpService(ISLookUpService lookUpService) {
		this.lookUpService = lookUpService;
	}
	

	/**
	 * Gets the result set service.
	 * 
	 * @return the result set service
	 */
	public ResultSetService getResultSetService() {
		return resultSetService;
	}

	
	/**
	 * Sets the result set service.
	 * 
	 * @param resultSetService the new result set service
	 */
	public void setResultSetService(ResultSetService resultSetService) {
		this.resultSetService = resultSetService;
	}
	

	/**
	 * Gets the registry service.
	 * 
	 * @return the registry service
	 */
	public ISRegistryService getRegistryService() {
		return registryService;
	}

	/**
	 * Sets the registry service.
	 * 
	 * @param registryService the new registry service
	 */
	public void setRegistryService(ISRegistryService registryService) {
		this.registryService = registryService;
	}

	public IFeatureExtractionService getFesService() {
		return this.fesService;
	}

	public void setFesService(IFeatureExtractionService fesService) {
		this.fesService = fesService;
	}
	
	public IDataAccessService getDataAccessService() {
		return this.dataAccessService;
	}

	public void setDataAccessService (IDataAccessService dataAccessService) {
		this.dataAccessService = dataAccessService;
	}
	
	public IDepotService getDepotService() {
		return this.depotService;
	}

	public void setDepotService (IDepotService depotService) {
		this.depotService = depotService;
	}
	
	public IMDStoreService getMdstoreService() {
		return this.mdstoreService;
	}

	public void setMdstoreService(IMDStoreService mdstoreService) {
		this.mdstoreService = mdstoreService;
	}
	
	public IIndexService getIndexService() {
		return this.indexService;
	}

	public void setIndexService(IIndexService indexService) {
		this.indexService = indexService;
	}
	
	/**
	 * Returns current service version.
	 * 
	 * @return current service version
	 */
	public String getServiceVersion() {
		return this.serviceVersion;
	}

	/**
	 * Sets current service version.
	 * 
	 * @param serviceVersion the service version
	 */
	public void setServiceVersion(String serviceVersion) {
		this.serviceVersion = serviceVersion;
	}
	
	/**
	 * Returns ResultSetIterator single call result size.
	 * 
	 * @return ResultSetIterator single call result size
	 */
	public int getRsPackageSize() {
		return this.rsPackageSize;
	}

	/**
	 * Sets ResultSetIterator single call result size.
	 * 
	 * @param rsPackageSize the rs package size
	 */
	public void setRsPackageSize(int rsPackageSize) {
		this.rsPackageSize = rsPackageSize;
	}

	/**
	 * Returns ResultSetIterator queue size.
	 * 
	 * @return ResultSetIterator queue size
	 */
	public int getRsQueueSize() {
		return this.rsQueueSize;
	}

	/**
	 * Sets ResultSetIterator queue size.
	 * 
	 * @param rsQueueSize the rs queue size
	 */
	public void setRsQueueSize(int rsQueueSize) {
		this.rsQueueSize = rsQueueSize;
	}

	/**
	 * Returns maximum timeout (in seconds) for retrieving single result from
	 * ResultSet while storing records.
	 * 
	 * @return maximum timeout (in seconds) for retrieving single result from
	 * ResultSet while storing records
	 */
	public long getMaxRSIteratorTimeout() {
		return this.maxRSIteratorTimeout;
	}

	/**
	 * Sets maximum timeout (in seconds) for retrieving single result from
	 * ResultSet while storing records.
	 * 
	 * @param maxRSIteratorTimeout the max rs iterator timeout
	 */
	public void setMaxRSIteratorTimeout(long maxRSIteratorTimeout) {
		this.maxRSIteratorTimeout = maxRSIteratorTimeout;
	}
	
	/**
	 * Gets the rs closing timeout.
	 * 
	 * @return the rs closing timeout
	 */
	public int getRsClosingTimeout() {
		return this.rsClosingTimeout;
	}

	/**
	 * Sets the rs closing timeout.
	 * 
	 * @param rsClosingTimeout the new rs closing timeout
	 */
	public void setRsClosingTimeout(int rsClosingTimeout) {
		this.rsClosingTimeout = rsClosingTimeout;
	}
	
	/**
	 * Returns result set expiry time.
	 * 
	 * @return result set expiry time
	 */
	public int getExpiryTime() {
		return expiryTime;
	}

	/**
	 * Sets result set expiry time.
	 * 
	 * @param expiryTime
	 */
	public void setExpiryTime(int expiryTime) {
		this.expiryTime = expiryTime;
	}
	
	/**
	 * Returns keep alive time.
	 * @return keep alive time
	 */
	public int getKeepAliveTime() {
		return keepAliveTime;
	}

	/**
	 * Sets keep alive time.
	 * @param keepAliveTime
	 */
	public void setKeepAliveTime(int keepAliveTime) {
		this.keepAliveTime = keepAliveTime;
	}
	
	public String getStoreBackendAddress() {
		return storeBackendAddress;
	}

	public void setStoreBackendAddress(String storeBackendAddress) {
		this.storeBackendAddress = storeBackendAddress;
	}
	
}
