/******************************************************************************
 * CrudLogicImpl.java - created by Sakai App Builder -AZ
 * 
 * Copyright (c) 2007 Sakai Project/Sakai Foundation
 * Licensed under the Educational Community License version 1.0
 * 
 * A copy of the Educational Community License has been included in this 
 * distribution and is available at: http://www.opensource.org/licenses/ecl1.php
 * 
 *****************************************************************************/

package org.sakaiproject.wontovlab.logic.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.sakaiproject.wontovlab.dao.ExperimentDao;
import org.sakaiproject.wontovlab.logic.ExperimentLogic;
import org.sakaiproject.wontovlab.logic.ExternalLogic;
import org.sakaiproject.wontovlab.logic.UtilLogic;
import org.sakaiproject.wontovlab.model.Experiment;
import org.springframework.util.FileCopyUtils;



/**
 * This is the implementation of the business logic interface
 * @author Sakai App Builder -AZ
 */
public class ExperimentLogicImpl implements ExperimentLogic 
{

	public ExperimentLogicImpl() {
		System.out.println("******************** TOM CAT INICIALIZADO ********************");
	}
	
	
	private static Log log = LogFactory.getLog(ExperimentLogicImpl.class);

	private ExperimentDao dao;
	public void setDao(ExperimentDao dao) {
		this.dao = dao;
	}

	private ExternalLogic externalLogic;
	public void setExternalLogic(ExternalLogic externalLogic) {
		this.externalLogic = externalLogic;
	}
	
	private UtilLogic utilLogic;
	public void setUtilLogic(UtilLogic utilLogic) {
		this.utilLogic = utilLogic;
	}

	/**
	 * Place any code that should run when this class is initialized by spring here
	 */
	public void init() {
		log.debug("init");
	}

    /**
     * List all Experiments in the hibernate
     *  
     */
    public List listExperiments(String locationId, String userId) 
    {
        log.info("[" + this.getClass() + "] listExperiments()");        	
		//List l = dao.findByLocation(locationId);
		List l = dao.findAllExperiments();

		return l;

    }
    
    public List listExperimentByExperimentName(String experimentName) {
		List l = dao.findExperimentByExperimentName(experimentName);
		return l;
    }
    
	public List findExperimentByExperimentId(Long experimentId) {
		return dao.findExperimentByExperimentId(experimentId);
	}
    
    public void saveExperiment(Experiment experiment)
    {
		log.debug("In saveExperiment with Experiment:" + experiment.getName());
		// set the owner and site to current if they are not set
		if (experiment.getOwnerId() == null) {
			experiment.setOwnerId( externalLogic.getCurrentUserId() );
		}


		// save Experiment if new OR check if the current user can update the existing Experiment
		if ( ((experiment.getExperimentId() == null) && canCreateExperiments(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId())) || 
				canEditExperiment(experiment, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
		{
			
			dao.saveExperiment(experiment);
			log.info("Saving Experiment: " + experiment.getExperimentId() + ":" + experiment.getName());
		} 
		else 
		{
			throw new SecurityException("Current user cannot update Experiment " + 
					experiment.getExperimentId() + " because the user do not have permission");
		}
    	
   	
    }
    
    public void removeExperiment(Experiment experiment)
    {
		log.debug("In removeExperiment with Experiment:" + experiment.getExperimentId() + ":" + experiment.getName());
		// check if current user can remove this Experiment
		if (canDeleteExperiment(experiment, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId() ) ) 
		{
			dao.deleteExperiment(experiment);
			log.info("Removing Experiment: " + experiment.getExperimentId() + ":" + experiment.getName());
		} 
		else 
		{
			throw new SecurityException("Current user cannot remove Experiment " + 
					experiment.getExperimentId() + " because the user do not have permission");
		}
    	
    }
    
    
    /**
     * Stores the photo related to a specific Experiment.
     */
    public void saveExperimentImage(Experiment experiment, String fileName, InputStream data) throws IOException
    {
    	log.debug("Storing image related to Experiment: " + experiment.getName() + ": id: " + experiment.getExperimentId());
    	String uploadFilePath = externalLogic.getSakaiHomePath() + externalLogic.getSakaiPropertyValue("lv.experiment.image.path");
    	
    	File file=new File(uploadFilePath);
    	
		if (!file.exists())
		{
			file.mkdir();
		}
		
		File file2 = new File(fileName);
		
		fileName = file2.getName();
		
		String finalFileName = "wbImage_" + experiment.getExperimentId() + "_" + fileName;
		
		
		file=new File(uploadFilePath+finalFileName);
		
		file.createNewFile();
		FileCopyUtils.copy(FileCopyUtils.copyToByteArray(data),file);
		file = null; //Free the resources
    }
    
    
    /**
     * Delete all photos related to a specific Experiment.
     * @param ExperimentId
     * @return
     */
    public boolean deleteExperimentImage(long experimentId)
    {
    	
    	log.debug("Deleting image related to Experiment with Id: " + experimentId);
    	String uploadFilePath = externalLogic.getSakaiHomePath() + externalLogic.getSakaiPropertyValue("lv.experiment.image.path");
    	
    	File dir=new File(uploadFilePath);
    	
    	if (!dir.exists())
    	{
    		return false;
    	}
    	
    	
    	List<File> files = utilLogic.listServerDirectoryFiles(dir, "wbImage_" + experimentId);
    	
    	if (files == null)
    	{
    		return false;
    	}
    	
    	
    	for (Iterator<File> iterator = files.iterator(); iterator.hasNext();)
		{
			File file = iterator.next();			
			file.delete();			
		}
    	
    	return true;

    }
        
    /**
     * Returns the name of a Experiment image, or null if there is no image available.
     */
    public String getExperimentImageName(Experiment experiment)
    {
    	log.debug("Retrieving the name of the image of the Experiment with Id: " + experiment.getExperimentId());
    	String uploadFilePath = externalLogic.getSakaiHomePath() + externalLogic.getSakaiPropertyValue("lv.experiment.image.path");
    	
    	File dir=new File(uploadFilePath);
    	
    	if (!dir.exists())
    	{
    		return null;
    	}
    	
    	
    	List<File> files = utilLogic.listServerDirectoryFiles(dir, "wbImage_" + experiment.getExperimentId());
    	
    	if (files == null)
    	{
    		return null;
    	}
    	
    	
    	for (Iterator<File> iterator = files.iterator(); iterator.hasNext();)
		{
			File file = iterator.next();			
			return file.getName();			
		}
    	
    	return null;
    }
    

	public boolean canEditExperiment(Experiment experiment, String locationId, String userId) 
	{
		log.debug("checking if can edit for: " + userId + ", " + locationId + ": and Experiment=" + experiment.getName() );
		if (experiment.getOwnerId().equals(userId)) 
		{
			// owner can always modify an Experiment
			return true;
		} 
		else if (externalLogic.isUserAdmin(userId)) 
		{
			// the system super user can modify any Experiment
			return true;
		} 
		else if (externalLogic.isUserAllowedInLocation(userId, ExternalLogic.Experiment_EDIT, locationId) ) 
		{
			// users with permission in the specified site can modify Experiments from that site
			return true;
		}
		return false;
	}
	
	public boolean canDeleteExperiment(Experiment experiment, String locationId, String userId) 
	{
		log.debug("checking if can delete for: " + userId + ", " + locationId + ": and Experiment=" + experiment.getName() );
		if (experiment.getOwnerId().equals(userId)) 
		{
			// owner can always delete an Experiment
			return true;
		} 
		else if (externalLogic.isUserAdmin(userId)) 
		{
			// the system super user can delete any Experiment
			return true;
		} 
		else if (externalLogic.isUserAllowedInLocation(userId, ExternalLogic.Experiment_DELETE, locationId) ) 
		{
			// users with permission in the specified site can delete Experiments from that site
			return true;
		}
		return false;
	}
	
	public boolean canCreateExperiments(String locationId, String userId) 
	{
		log.debug("checking if can create for: " + userId + ", " + locationId);
		if (externalLogic.isUserAdmin(userId)) 
		{
			// the system super user can create any Experiment
			return true;
		} 
		
		if (externalLogic.isUserAllowedInLocation(userId, ExternalLogic.Experiment_CREATE, locationId)) 
		{
			// users with permission in the specified site can create Experiments from that site
			return true;
			
		}
		return false;
	}
	
	public boolean canReadExperiment(Experiment experiment, String locationId, String userId) 
	{
		log.debug("checking if can read for: " + userId + ", " + locationId + ": and Experiment=" + experiment.getName() );
		if (experiment.getOwnerId().equals(userId)) 
		{
			// owner can always read an Experiment
			return true;
		} 
		else if (externalLogic.isUserAdmin(userId)) 
		{
			// the system super user can read any Experiment
			return true;
		} 
		else if (externalLogic.isUserAllowedInLocation(userId, ExternalLogic.Experiment_CREATE, locationId) ) 
		{
			// users with permission in the specified site can read Experiments from that site
			return true;
		}
		return false;
	}

	


}
