/**
 * 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.File;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;

import org.apache.log4j.Logger;

import eu.dnetlib.data.mdstore.auth.ServiceAuthentication;
import eu.dnetlib.data.udm.DataCollectionCreatingThread.COLECTION_TYPE;
import eu.dnetlib.data.udm.cron.CronJobs;


/**
 * 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 ws ctxt. */
	@Resource
	WebServiceContext wsCtxt;
	
	/** The Constant LOGGER. */
	private final static Logger LOGGER = Logger.getLogger(UsageDataMergingService.class);
	
	/** The service version. */
	private String serviceVersion;
	
	/** The servlet directory. */
	private String servletDirectory;
	
	/** The cron jobs. */
	private CronJobs cronJobs;
	
	/** The authentication file path. */
	private String authenticationFilePath;
	
	/** The authentication. */
	private boolean authentication;
	
	/**
	 * Inits the.
	 */
	public void init() {
		
		createDirectory(servletDirectory);
	}

	
	/* (non-Javadoc)
	 * @see eu.dnetlib.data.udm.IUsageDataMergingService#createCompleteDataCollection()
	 */
	public void createCompleteDataCollection () 
		throws UsageDataMergingServiceException {
		
		if (!authentication(ServiceAuthentication.AUTHENTICATION_TYPE_IP_WRITE_ACCESS)) {
			LOGGER.error("Authentication failed!");
			throw new UsageDataMergingServiceException("Authentication failed! " +
					"You are not allowed to use this service.");	
		}
		
		try {
			LOGGER.info("Creating Complete Data Collection!");
			DataCollectionCreatingThread dcct = new DataCollectionCreatingThread(null, 
					COLECTION_TYPE.COMPLETE, getCronJobs());
			Thread thread = new Thread(dcct);
			thread.start();
		} catch (Exception e) {
			throw new UsageDataMergingServiceException(e);
		}
	}
	
	/* (non-Javadoc)
	 * @see eu.dnetlib.data.udm.IUsageDataMergingService#createYesterdaysDataCollection(java.lang.String)
	 */
	public void createYesterdaysDataCollection (String storingDate) 
		throws UsageDataMergingServiceException {
		
		if (!authentication(ServiceAuthentication.AUTHENTICATION_TYPE_IP_WRITE_ACCESS)) {
			LOGGER.error("Authentication failed!");
			throw new UsageDataMergingServiceException("Authentication failed! " +
					"You are not allowed to use this service.");	
		}
		
		try {
			LOGGER.info("Creating Yesterdays Data Collection!");
			DataCollectionCreatingThread dcct = new DataCollectionCreatingThread(
					storingDate, COLECTION_TYPE.YESTERDAY, getCronJobs());
			Thread thread = new Thread(dcct);
			thread.start();
		} catch (Exception e) {
			throw new UsageDataMergingServiceException(e);
		}
	}
	
	/**
	 * Creates the directory.
	 * 
	 * @param directoryPath the directory path
	 */
	private void createDirectory(String directoryPath) {
		
		File directoryFile = new File(directoryPath);
		LOGGER.debug("Crating download directory: " + 
				directoryFile.getAbsolutePath());
		if (!directoryFile.exists()) {
			if (!directoryFile.mkdirs())
				throw new RuntimeException("Could not create "
						+ "main storage directory, please check your "
						+ "access rights for the following location: "
						+ directoryFile.getAbsolutePath());
		} else {
			if (!directoryFile.canWrite()) 
				throw new RuntimeException("Can not write to the " +
						"directory, please check your " +
						"access rights for this location: "+
						directoryFile.getAbsolutePath());	
		}
	}
	
	/**
	 * Authentication.
	 * 
	 * @param authenticationType the authentication type
	 * 
	 * @return true, if successful
	 * 
	 * @throws AuthenticationFailedException the authentication failed exception
	 */
	public boolean authentication(String authenticationType) {
		
		if (getAuthentication()) {
			
			MessageContext msgCtxt = wsCtxt.getMessageContext();
			//in case of junit tests
			if (msgCtxt == null)
				return true;
			HttpServletRequest httpRequest = (HttpServletRequest)msgCtxt.get(MessageContext.SERVLET_REQUEST);
			
			ServiceAuthentication serviceAuthentication = 
				new ServiceAuthentication(authenticationFilePath);
			serviceAuthentication.setRequest(httpRequest);
			boolean auth = serviceAuthentication.authenticate(authenticationType);
			LOGGER.info("Client '" + 
				serviceAuthentication.getClientIP()+"' authentication: "+ auth );
	
			return auth;
		} else 
			return true;
	}
	
	/**
	 * Gets the servlet directory.
	 * 
	 * @return the servletDirectory
	 */
	public String getServletDirectory() {
		return servletDirectory;
	}

	/**
	 * Sets the servlet directory.
	 * 
	 * @param servletDirectory the servletDirectory to set
	 */
	public void setServletDirectory(String servletDirectory) {
		this.servletDirectory = servletDirectory;
	}

	/* (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;
	}


	/**
	 * @param cronJobs the cronJobs to set
	 */
	public void setCronJobs(CronJobs cronJobs) {
		this.cronJobs = cronJobs;
	}


	/**
	 * @return the cronJobs
	 */
	public CronJobs getCronJobs() {
		return cronJobs;
	}
	
	/**
	 * Sets the authentication file path.
	 * 
	 * @param authenticationFilePath the authenticationFilePath to set
	 */
	public void setAuthenticationFilePath(String authenticationFilePath) {
		this.authenticationFilePath = authenticationFilePath;
	}

	/**
	 * Gets the authentication file path.
	 * 
	 * @return the authenticationFilePath
	 */
	public String getAuthenticationFilePath() {
		return authenticationFilePath;
	}

	/**
	 * Sets the authentication.
	 * 
	 * @param authentication the authentication to set
	 */
	public void setAuthentication(boolean authentication) {
		this.authentication = authentication;
	}

	/**
	 * Gets the authentication.
	 * 
	 * @return the authentication
	 */
	public boolean getAuthentication() {
		return authentication;
	}

}
