/**
 * Copyright 2009-2012 OpenAIRE PROJECT (Bielefeld University)
 * Original author: Marek Imialek <marek.imialek at uni-bielefeld.de>
 *
 * 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.data.udm;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.annotation.Resource;
import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.log4j.Logger;

import eu.dnetlib.data.udm.is.ISInteractions;
import eu.dnetlib.data.udm.mdstore.MDStoreInteractions;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.enabling.tools.ServiceLocator;


/**
 * The Class UsageDataMergingService is a main facade of Usage Data Merging
 * Service implementing service interface IUsageDataMergingService.
 * 
 * @author <a href="mailto:marek.imialek at uni-bielefeld.de">Marek Imialek</a>
 */
public class UsageDataMergingService implements IUsageDataMergingService{


	/** The service version. */
	private String serviceVersion;
	
	/** The is interactions. */
	private ISInteractions isInteractions;

	/** The resultset locator. */
	@Resource(name="resultsetLocator")
	protected ServiceLocator<ResultSetService> resultsetLocator;
	
	/** The expiry time. */
	private int expiryTime;

	/** The keep alive time. */
	private int keepAliveTime;

	/** The deliver preferences. */
	private DeliveryPreferences deliverPreferences;
	
	/** The Constant LOGGER. */
	private final static Logger LOGGER = Logger.getLogger(UsageDataMergingService.class);
	
	/**
	 * Inits the.
	 */
	public void init() {}

	/* (non-Javadoc)
	 * @see eu.dnetlib.data.udm.IUsageDataMergingService#getAllRecords(java.lang.String, java.lang.String)
	 */
	public W3CEndpointReference getAllRecords(String dateFrom, String dateUntil)
			throws UsageDataMergingServiceException {
		
		LOGGER.info("METHOD getAllRecords has " +
				"been issued with the following parameters: ");
		LOGGER.info("dateFrom: " + dateFrom);
		LOGGER.info("dateUntil: " + dateUntil);
		try {
			W3CEndpointReference outRsEPR = resultsetLocator.getService().createPushRS(expiryTime, keepAliveTime);
			LOGGER.info("Push RS EPR:" +outRsEPR);
			DeliverUsageData deliverUsageData = new DeliverUsageData(dateFrom, dateUntil,
					isInteractions, outRsEPR, getDeliverPreferences());
			
			new Thread(deliverUsageData).start();
			LOGGER.debug("Process of delivering usage data send to the background, back to the client!");
			
			return outRsEPR;
		} catch (Exception e){
			StringWriter sw = new StringWriter();
		    PrintWriter pw = new PrintWriter(sw, true);
		    e.printStackTrace(pw);
		    pw.flush();
		    sw.flush();
		    LOGGER.error(sw.toString());
			throw new UsageDataMergingServiceException(e);	
		}
	}
	

	/* (non-Javadoc)
	 * @see eu.dnetlib.data.udm.IUsageDataMergingService#getRepositoryRecords(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
	 */
	public W3CEndpointReference getRepositoryRecords(String dateFrom, String dateUntil,
			String repositoryIdentifier, String sortBy) throws UsageDataMergingServiceException {
		
		if (repositoryIdentifier == null || repositoryIdentifier.equals(""))
			throw new UsageDataMergingServiceException ("Repository identifier parameter can not be null!");
		
		LOGGER.info("METHOD getRepositoryRecords has " +
			"been issued with the following parameters: ");
		LOGGER.info("dateFrom: " + dateFrom);
		LOGGER.info("dateUntil: " + dateUntil);
		LOGGER.info("RepositoryId: " + repositoryIdentifier);
		LOGGER.info("SortBy: " + sortBy);
		
		try {
			return (MDStoreInteractions.deliverMDStoreEPR(
					repositoryIdentifier, dateFrom, dateUntil, sortBy,isInteractions)).getMDStoreResultSetEpr();
		} catch (Exception e){
			LOGGER.error(e.getLocalizedMessage());
			throw new UsageDataMergingServiceException(e);	
		}
	}
	
	/* (non-Javadoc)
	 * @see eu.dnetlib.data.udm.IUsageDataMergingService#identify()
	 */
	public String identify() {
		return this.getServiceVersion();
	}


	/**
	 * Sets the service version.
	 * 
	 * @param serviceVersion the serviceVersion to set
	 */
	public void setServiceVersion(String serviceVersion) {
		this.serviceVersion = serviceVersion;
	}


	/**
	 * Gets the service version.
	 * 
	 * @return the serviceVersion
	 */
	public String getServiceVersion() {
		return serviceVersion;
	}

	/**
	 * Sets the is interactions.
	 * 
	 * @param isInteractions the isInteractions to set
	 */
	public void setIsInteractions(ISInteractions isInteractions) {
		this.isInteractions = isInteractions;
	}

	/**
	 * Gets the is interactions.
	 * 
	 * @return the isInteractions
	 */
	public ISInteractions getIsInteractions() {
		return isInteractions;
	}

	/**
	 * Gets the resultset locator.
	 * 
	 * @return the resultset locator
	 */
	public ServiceLocator<ResultSetService> getResultsetLocator() {
		return resultsetLocator;
	}

	/**
	 * Sets the resultset locator.
	 * 
	 * @param resultsetLocator the new resultset locator
	 */
	public void setResultsetLocator(
			ServiceLocator<ResultSetService> resultsetLocator) {
		this.resultsetLocator = resultsetLocator;
	}
	
	/**
	 * Gets the expiry time.
	 * 
	 * @return the expiryTime
	 */
	public int getExpiryTime() {
		return expiryTime;
	}

	/**
	 * Sets the expiry time.
	 * 
	 * @param expiryTime the expiryTime to set
	 */
	public void setExpiryTime(int expiryTime) {
		this.expiryTime = expiryTime;
	}

	/**
	 * Gets the keep alive time.
	 * 
	 * @return the keepAliveTime
	 */
	public int getKeepAliveTime() {
		return keepAliveTime;
	}

	/**
	 * Sets the keep alive time.
	 * 
	 * @param keepAliveTime the keepAliveTime to set
	 */
	public void setKeepAliveTime(int keepAliveTime) {
		this.keepAliveTime = keepAliveTime;
	}

	/**
	 * Sets the deliver preferences.
	 * 
	 * @param deliverPreferences the deliverPreferences to set
	 */
	public void setDeliverPreferences(DeliveryPreferences deliverPreferences) {
		this.deliverPreferences = deliverPreferences;
	}

	/**
	 * Gets the deliver preferences.
	 * 
	 * @return the deliverPreferences
	 */
	public DeliveryPreferences getDeliverPreferences() {
		return deliverPreferences;
	}
}
