/******************************************************************************
 * 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.MaterialDao;
import org.sakaiproject.wontovlab.logic.ExternalLogic;
import org.sakaiproject.wontovlab.logic.MaterialLogic;
import org.sakaiproject.wontovlab.logic.UtilLogic;
import org.sakaiproject.wontovlab.model.Drug;
import org.sakaiproject.wontovlab.model.Equipment;
import org.sakaiproject.wontovlab.model.Material;
import org.sakaiproject.wontovlab.model.Solution;
import org.springframework.util.FileCopyUtils;



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

	public MaterialLogicImpl() {
	}
	
	
	private static Log log = LogFactory.getLog(MaterialLogicImpl.class);

	private MaterialDao dao;
	public void setDao(MaterialDao 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 listMaterial(String locationId, String userId) 
    {
        log.info("[" + this.getClass() + "] listMaterials()");        	
		List l = dao.findAllMaterials();

		return l;

    }
    public void saveMaterial(Material material)
    {
/*		log.debug("In saveExperiment with Experiment:" + experiment.getNome());
		// 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.getIdExp() == null) && canCreateExperiments(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId())) || 
				canEditExperiment(experiment, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
		{
			
			dao.saveExperiment(experiment);
			log.info("Saving Experiment: " + experiment.getIdExp() + ":" + experiment.getNome());
		} 
		else 
		{
			throw new SecurityException("Current user cannot update Experiment " + 
					experiment.getIdExp() + " because the user do not have permission");
		}*/
    	
   	
    }
    
	public List listMaterialByDescription(String material) {
		List l = dao.findMaterialByDescription(material);

		return l;
	}
    
    public List listDrug(String locationId, String userId) 
    {
        log.info("[" + this.getClass() + "] listDrugs()");        	
		List l = dao.findAllDrugs();

		return l;

    }
    public void saveDrug(Drug drug)
    {
		log.debug("In save Drug");



		// save Experiment if new OR check if the current user can update the existing Experiment
		if ( ((drug.getMaterialId() == null) && canCreateMaterial(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId())) || 
				canEditMaterial(drug, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
		{
			
			dao.saveDrug(drug);
			log.info("Saving Drug: " + drug.getMaterialId() );
		} 
		else 
		{
			throw new SecurityException("Current user cannot update Drug " + 
					drug.getMaterialId() + " because the user do not have permission");
		}
    	
   	
    }
    
    public List listEquipment(String locationId, String userId) 
    {
        log.info("[" + this.getClass() + "] listEquipments()");        	
		List l = dao.findAllEquipments();

		return l;

    }
    public void saveEquipment(Equipment equipment)
    {
		log.debug("In save Equipment");


		// save Experiment if new OR check if the current user can update the existing Experiment
		if ( ((equipment.getMaterialId() == null) && canCreateMaterial(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId())) || 
				canEditMaterial(equipment, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
		{
			
			dao.saveEquipment(equipment);
			log.info("Saving Equipment: " + equipment.getMaterialId() );
		} 
		else 
		{
			throw new SecurityException("Current user cannot update Equipment" + 
					equipment.getMaterialId() + " because the user do not have permission");
		}
    	
   	
    }
    
    
    
    
    public List listSolution(String locationId, String userId) 
    {
        log.info("[" + this.getClass() + "] listSolution()");        	
		List l = dao.findAllSolutions();

		return l;

    }
    public void saveSolution(Solution solution)
    {
		log.debug("In save Equipment");


		// save Experiment if new OR check if the current user can update the existing Experiment
		if ( ((solution.getMaterialId() == null) && canCreateMaterial(externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId())) || 
				canEditMaterial(solution, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId()) ) 
		{
			
			dao.saveSolution(solution);
			log.info("Saving Solution: " + solution.getMaterialId() );
		} 
		else 
		{
			throw new SecurityException("Current user cannot update Equipment" + 
					solution.getMaterialId() + " because the user do not have permission");
		}
    	
   	
    }
    
    
    
    
    
	public void removeDrug(Drug drug) {
		log.debug("In remove drug:" + drug.getDescription() );
		// check if current user can remove this Experiment
		
		if (canDeleteMaterial(drug, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId() ) ) 
		{
			dao.deleteDrug(drug);
			log.info("Removing Drug: " + drug.getDescription());
		} 
		else 
		{
			throw new SecurityException("Current user cannot remove drug " + 
					drug.getDescription() + " because the user do not have permission");
		}
	}
	public void removeEquipment(Equipment equipment){
		log.debug("In remove equipment:" + equipment.getDescription() );
		// check if current user can remove this Experiment
		
		if (canDeleteMaterial(equipment, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId() ) ) 
		{
			dao.deleteEquipment(equipment);
			log.info("Removing Equipment: " + equipment.getDescription());
		} 
		else 
		{
			throw new SecurityException("Current user cannot remove equipment " + 
					equipment.getDescription() + " because the user do not have permission");
		}
		
	}
	public void removeSolution(Solution solution){
		log.debug("In remove equipment:" + solution.getDescription() );
		// check if current user can remove this Experiment
		
		if (canDeleteMaterial(solution, externalLogic.getCurrentLocationId(), externalLogic.getCurrentUserId() ) ) 
		{
			dao.deleteSolution(solution);
			log.info("Removing Solution: " + solution.getDescription());
		} 
		else 
		{
			throw new SecurityException("Current user cannot remove equipment " + 
					solution.getDescription() + " because the user do not have permission");
		}
		
	}
	
	public boolean canEditMaterial(Material materials, String locationId, String userId) 
	{
		log.debug("Trying edit material " + materials.getDescription());
		
		if (materials.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 canDeleteMaterial(Material materials, String locationId, String userId) 
	{
		log.debug("Trying delete material " + materials.getDescription());

		if (materials.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 canCreateMaterial(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;*/
		return true;
	}
	
	public boolean canReadMaterial(Material material, String locationId, String userId) 
	{
/*		log.debug("checking if can read for: " + userId + ", " + locationId + ": and Experiment=" + experiment.getNome() );
		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;*/
		return true;
	}

	
    public void saveMaterialImage(Long materialId, String fileName, InputStream data) throws IOException
    {
    	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();
		
		System.out.println("****************************");
		System.out.println("SALVANDO ARQUIVO: " + fileName);
		System.out.println("****************************");
		
		String finalFileName = "materialImage_" + materialId + "_" + fileName;
		
		file=new File(uploadFilePath+finalFileName);
		
		file.createNewFile();
		FileCopyUtils.copy(FileCopyUtils.copyToByteArray(data),file);
		file = null; //Free the resources
    }

    public String getMaterialImageName(Long materialId)
    {
    	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, "materialImage_" + materialId + "_");
    	
    	if (files == null)
    	{
    		return null;
    	}
    	
    	
    	for (Iterator<File> iterator = files.iterator(); iterator.hasNext();)
		{
			File file = iterator.next();			
			return file.getName();			
		}
    	
    	return null;
    }
}
