/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.letter.ejb.session.beans;

import java.util.List;

import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import lu.tudor.santec.gecamed.core.utils.FileUtils;
import lu.tudor.santec.gecamed.core.utils.ServerConfig;
import lu.tudor.santec.gecamed.letter.ejb.entity.beans.LetterTemplate;
import lu.tudor.santec.gecamed.letter.ejb.session.interfaces.LetterTemplateInterface;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;


@Stateless
@Remote (LetterTemplateInterface.class)

/*
 * SessionBean that manages the LetterTemplateBeans
 */

public class LetterTemplateBean implements LetterTemplateInterface{

	@PersistenceContext (unitName="gecam") private EntityManager em;
	
	/**
	 * static logger for this class
	 */
	private static Logger logger = Logger
		.getLogger(LetterTemplateBean.class.getName());
	
	//add e new template
	public LetterTemplate addTemplate(LetterTemplate template) {
		try {
			template = em.merge(template);
			em.flush();
			return template;
		} catch (Exception e) {
			logger.log(Level.WARN, "error adding template ", e);
			return null;
		}
	}
	
	
	
	public String saveFile(byte[] b, String name, Integer patientId) {
		/* ================================================== */
		// Saving the file on the server
		try {
			String generated_filename = FileUtils
					.saveGECAMedPatientFile(
							b,
							name,
							ServerConfig.getProperty(ServerConfig.PATIENT_FILES_DIR),
							patientId);
			return generated_filename;
		} catch (Exception e) {
		    	logger.log(Level.WARN, "error saving template file", e);
			return null;
		}
		/* ================================================== */
	}
	
	public byte[] getFile(String originalFilename, Integer id) {
		/* ================================================== */
		byte[] filebytes;
		try {
			filebytes = FileUtils.getGECAMedPatientFile(originalFilename,
								ServerConfig.getProperty(ServerConfig.PATIENT_FILES_DIR),
								id);
			return filebytes;
		} catch (Exception e) {
		    	logger.log(Level.WARN, "error reading template file", e);
			return null;
		}
		
		/* ================================================== */
	}
	
	
	//get a all template
	@SuppressWarnings("unchecked")
	public List<LetterTemplate> getFilteredTemplates (Integer physicianId, String typeFilter, String nameFilter)
	{
//		@SuppressWarnings("unchecked")
//		List<LetterTemplate> result = em.createNamedQuery(LetterTemplate.FILTER_TEMPLATES)
//				.setParameter("physicianId", physicianId)
//				.setParameter("type", typeFilter )
//				.setParameter("name", "%"+nameFilter+"%")
//				.getResultList();
		
		StringBuilder	queryString;
		Query			query;
		
		
		queryString	= new StringBuilder("SELECT OBJECT(t) FROM LetterTemplate t")
				.append("\nWHERE (t.share = true OR t.physicianId = :physicianId)");
		
		if (typeFilter != null)
			queryString.append("\nAND t.type = :type");
		
		if (nameFilter != null)
			queryString.append("\nAND lower(t.name) LIKE :name");
				
		queryString.append("\nORDER BY t.type, t.name ASC");
		
		query = em.createQuery(queryString.toString()).setParameter("physicianId", physicianId);
		
		if (typeFilter != null)
			query.setParameter("type", typeFilter);
		
		if (nameFilter != null)
			query.setParameter("name", "%"+nameFilter+"%");
		
		return query.getResultList();
	}
	

	//get all templates of a physician
	@SuppressWarnings("unchecked")
	public List<LetterTemplate> getTemplatesByPhysycian(int id) {
		List<LetterTemplate> result = em.createNamedQuery(
				LetterTemplate.FIND_ALL_BY_PHYSICIAN_ID).setParameter("physician_id", id).getResultList();
		return result;
	}

	//get the binaries of a file on the server that corresponds to a template
	public byte[] getTemplateBinary(LetterTemplate template) throws Exception {
	    try {
		return FileUtils.getGECAMedFile(
			template.getGeneratedFileName(), ServerConfig.getProperty(ServerConfig.TEMPLATE_DIR));		
	    } catch (Exception e) {
		logger.log(Level.ERROR, "Error loading Template file.", e);
		throw e;
	    }
	}
	//create a file on the server that corresponds to a template
	public String setTemplateBinary(String fileName, byte[] binData) throws Exception {
		return FileUtils.saveGECAMedFile(binData, fileName, ServerConfig.getProperty(ServerConfig.TEMPLATE_DIR));
	}

	//remove a file on the server that corresponds to a template
	public boolean removeTemplate(LetterTemplate template) {
		try{
			LetterTemplate temp = em.find(LetterTemplate.class, template.getId());
			String	fileName = temp.getGeneratedFileName();
			em.remove(temp);
			
			FileUtils.deleteGECAMedFile(fileName, ServerConfig.getProperty(ServerConfig.TEMPLATE_DIR));
			
//			cleanUpTemplateFiles ();
			
			return true;
		}
		catch(Exception e){
		    	logger.log(Level.WARN, "error removing template", e);
			return false;
		}
	}
	
//	private void cleanUpTemplateFiles()
//	{
//		@SuppressWarnings("unchecked")
//		List<String> templates		= em.createQuery(
//				"SELECT o.generatedFileName FROM LetterTemplate o")
//				.getResultList();
//		File	templateDir		= new File(ServerConfig.getProperty(ServerConfig.TEMPLATE_DIR));
//		File[]	templateFiles	= templateDir.listFiles();
//		Set<String>	fileNameSet	= new HashSet<String>(templates);
//		String	templateFileName;
//		
//		for (File templateFile : templateFiles)
//		{
//			if (!fileNameSet.contains(templateFile.getName()))
//			{
//				templateFileName	= templateFile.getName();
//				try
//				{
//					templateFile.delete();
//					logger.info("Cleaned template file \"" + templateFileName + "\"!");
//				}
//				catch (Exception e)
//				{
//					logger.log(Level.WARN, "Couldn't delete template file \"" + templateFileName + "\".", e);
//				}
//			}
//		}
//	}



	//get types of templates
	@SuppressWarnings("unchecked")
	public List<String> getTypes(){	
		List<String> types = em.createNamedQuery(LetterTemplate.FIND_TYPES).getResultList();
		return types;
	}
	
	@SuppressWarnings("unchecked")
	public List<String> getTypesByPhysician(int id){
		List<String> types = em.createNamedQuery(LetterTemplate.FIND_TYPES_BY_PHYSICIAN_ID)
				.setParameter("physician_id", id)
				.getResultList();
		return types;
	}
	
	 
	
	public String getServerLetterDir() {
	    return ServerConfig.getProperty(ServerConfig.PATIENT_FILES_DIR);
	}



	public String getServerTemplateDir() {
	    return ServerConfig.getProperty(ServerConfig.TEMPLATE_DIR);
	}
	
	
	public LetterTemplate saveDetails (LetterTemplate template)
	{
		return em.merge(template);
	}
	
	
	public boolean doesTemplateNameAlreadyExist(String name)
	{
		List<?> result = em.createNamedQuery(LetterTemplate.FIND_TEMPLATE_BY_NAME)
				.setParameter("name", name)
				.setMaxResults(1)
				.getResultList();
		
		return result != null && result.size() > 0;
	}
}
