/*******************************************************************************
 * 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.labo.ejb.session.beans;

import java.security.cert.X509Certificate;
import java.util.Collection;

import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;

import lu.tudor.santec.gecamed.core.ejb.session.beans.GECAMedSessionBean;
import lu.tudor.santec.gecamed.labo.ejb.entity.beans.Connection;
import lu.tudor.santec.gecamed.labo.ejb.entity.beans.MasterPassword;
import lu.tudor.santec.gecamed.labo.ejb.entity.beans.PhysicianKey;
import lu.tudor.santec.gecamed.labo.ejb.session.interfaces.KeyChainInterface;
import lu.tudor.santec.gecamed.labo.ejb.session.interfaces.LaboratoryInterface;
import lu.tudor.santec.gecamed.labo.utils.LaboException;
import lu.tudor.santec.gecamed.labo.utils.SmimeDecoder;

import org.apache.log4j.Level;

@Stateless
@Remote (KeyChainInterface.class)

public class KeyChainBean extends GECAMedSessionBean implements KeyChainInterface
{

@EJB
LaboratoryInterface	m_LaboBean;



@RolesAllowed("gecam")
public MasterPassword getMasterPasswordByOfficeId (Integer p_OfficeId) throws Exception
	{
	MasterPassword l_Password = null;

	try	{
		l_Password = (MasterPassword) this.getEntityManager()
										  .createNamedQuery(MasterPassword.c_PasswordByOfficeId)
										  .setParameter(MasterPassword.c_OfficeIdParameter, p_OfficeId)
										  .getSingleResult();
		}
	catch (NoResultException p_Exception)
		{
		l_Password = null;
		}

	return l_Password;
	}
		
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
public	MasterPassword	saveMasterPassword (MasterPassword p_Password) throws Exception
	{
	if (p_Password == null) return null;
	
	return this.getEntityManager().merge(p_Password);
	}

//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <Connection> getConnectionsByPhysicianId (Integer p_PhysicianId) throws Exception
	{
	Collection <Connection> l_Connections = null;

	try	{
		l_Connections = this.getEntityManager()
							.createNamedQuery(Connection.c_ConnectionsByPhysicianId)
							.setParameter(Connection.c_PhysicianIdParameter, p_PhysicianId)
							.getResultList();
		}
	catch (NoResultException p_Exception)
		{
		l_Connections = null;
		}

	return l_Connections;
	}
	
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <Connection> getConnectionsByOfficeId (Integer p_OfficeId) throws Exception
	{
	Collection <Connection> l_Connections = null;

	try	{
		l_Connections = this.getEntityManager()
							.createNamedQuery(Connection.c_ConnectionsByOfficeId)
							.setParameter(Connection.c_OfficeIdParameter, p_OfficeId)
							.getResultList();
		}
	catch (NoResultException p_Exception)
		{
		l_Connections = null;
		}

	return l_Connections;
	}

//---------------------------------------------------------------------------

@RolesAllowed("gecam")
public	Connection	saveConnection (Connection p_Connection) throws Exception
	{
	if (p_Connection == null) return null;
	
	return this.getEntityManager().merge(p_Connection);
	}

//---------------------------------------------------------------------------

@RolesAllowed("gecam")
public	void	deleteConnection (Connection p_Connection) throws Exception
	{
	if ((p_Connection == null) || !p_Connection.isPersistent()) return;
	
	p_Connection = this.getEntityManager().find(Connection.class, p_Connection.getId());
	
	this.getEntityManager().remove(p_Connection);
	}

//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <PhysicianKey> getKeysByPhysicianId (Integer p_PhysicianId) throws Exception
	{
	Collection <PhysicianKey> l_Keys = null;

	try	{
		l_Keys = this.getEntityManager()
					 .createNamedQuery(PhysicianKey.c_KeysByPhysicianId)
					 .setParameter(PhysicianKey.c_PhysicianIdParameter, p_PhysicianId)
					 .getResultList();
		}
	catch (NoResultException p_Exception)
		{
		l_Keys = null;
		}

	return l_Keys;
	}
	
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <PhysicianKey> getKeysByOfficeId (Integer p_OfficeId) throws Exception
	{
	Collection <PhysicianKey> l_Keys = null;

	try	{
		l_Keys = this.getEntityManager()
					 .createNamedQuery(PhysicianKey.c_KeysByOfficeId)
					 .setParameter(PhysicianKey.c_OfficeIdParameter, p_OfficeId)
					 .getResultList();
		}
	catch (NoResultException p_Exception)
		{
		l_Keys = null;
		}

	return l_Keys;
	}

//---------------------------------------------------------------------------
	
	@RolesAllowed("gecam")
	public Integer isValidKey(PhysicianKey p_Key, String p_Password)
	{
		SmimeDecoder l_Decoder;
		int l_ErrorCode;
		
		if (p_Password == null || p_Password.trim().length() == 0)
			return Integer.valueOf(LaboException.ERROR_PASSWORD_NOT_SET);
		
		l_Decoder = new SmimeDecoder();
		try
		{
			l_Decoder.setupKeystore(p_Key, p_Password, m_LaboBean);
			l_ErrorCode = l_Decoder.getErrors();
		}
		catch (LaboException e)
		{
			l_ErrorCode = e.getErrorCode();
			this.log(Level.INFO, "Key " + p_Key.getLabel() + " is invalid! " + LaboException.getMessageForErrors(l_ErrorCode), e);
		}
		catch (Exception e)
		{
			l_ErrorCode = LaboException.ERROR_UNKNOWN;
			this.log(Level.INFO, "Key " + p_Key.getLabel() + " is invalid! " + LaboException.getMessageForErrors(l_ErrorCode), e);
		}
		
		return Integer.valueOf(l_ErrorCode);
	}

//---------------------------------------------------------------------------

@RolesAllowed("gecam")
public	PhysicianKey	saveKey (PhysicianKey p_Key) throws Exception
	{
	SmimeDecoder	l_Decoder;
	X509Certificate	l_Certificate;
	
	if (p_Key == null) return null;
	
	if (p_Key.getPemPublic() != null)
		{
		l_Decoder = new SmimeDecoder ();
		l_Certificate = l_Decoder.getCertificate(p_Key.getPemPublic(), m_LaboBean);
		if (l_Certificate != null) 
			p_Key.setExpiryDate(l_Certificate.getNotAfter());
		}
	
	return this.getEntityManager().merge(p_Key);
	}

//---------------------------------------------------------------------------

@RolesAllowed("gecam")
public	void	deleteKey (PhysicianKey p_Key) throws Exception
	{
	if ((p_Key == null) || !p_Key.isPersistent()) return;
	
	p_Key = this.getEntityManager().find(PhysicianKey.class, p_Key.getId());
	
	this.getEntityManager().remove(p_Key);
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	}
