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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.List;

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

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Act;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Activity;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Invoice;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.InvoiceStub;
import lu.tudor.santec.gecamed.billing.ejb.session.interfaces.StatisticsInterface;
import lu.tudor.santec.gecamed.core.ejb.session.beans.GECAMedSessionBean;
import lu.tudor.santec.gecamed.core.utils.querybuilder.HibernateQueryFactory;
import lu.tudor.santec.gecamed.core.utils.querybuilder.WhereClause;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.Patient;

//***************************************************************************
//* Interface Definition and Members                                        *
//***************************************************************************

/**
 * The StatisticsBean defines functionality to manage lists of performed
 * acts in order to generate statistics. The bean relies on Activity Beans
 * to improve performance when working with large numbers of acts. An Activity 
 * Bean is a composite view of performed acts, containing also data about the 
 * patient act was performed for. 
 * @author nico.mack@tudor.lu
 */

@Stateless
@Remote (StatisticsInterface.class)
public class StatisticsBean extends GECAMedSessionBean implements StatisticsInterface
{
	private static final long serialVersionUID = 1L;

//***************************************************************************
//* Class Primitives                                                        *
//***************************************************************************

//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body                                                              *
//***************************************************************************
//---------------------------------------------------------------------------
/**
 * Returns the number of activities matching the specified where clause.
 * @param p_Clause specifies the where clause that activities have to match
 * in order to be taken into account.
 * @return the number of matching activities.
 */
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Long	getActivityCountByWhereClause (WhereClause p_Clause) throws Exception
	{
	Query					l_Query;
	String					l_QueryString;

	Long					l_Count;
	
	if (p_Clause == null) return 0L;

	l_QueryString = "SELECT COUNT(o) FROM Activity o ";

	try	{
		l_Query = HibernateQueryFactory.buildQueryFromWhereClause (m_EntityManager,l_QueryString, p_Clause);
		l_Count = (Long) l_Query.getSingleResult();
		}
	catch (NoResultException p_Exception)
		{
		l_Count = 0L;
		}
	
	return l_Count;
	}

//---------------------------------------------------------------------------
/**
 * Fetches the activities matching the specified where clause.
 * @param p_Clause specifies the where clause that activities have to match
 * in order to be taken into account.
 * @return A collection holding the matching activities, an empty collection 
 * if none are found.
 */
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <Activity> getActivitiesByWhereClause (WhereClause p_Clause) throws Exception
	{
	Query					l_Query;
	String					l_QueryString;

	Collection <Activity>	l_Activities;

	l_Activities = new LinkedHashSet <Activity> ();
	
	if (p_Clause == null) return l_Activities;

	l_QueryString = "SELECT OBJECT(o) FROM Activity o ";

	try	{
		l_Query = HibernateQueryFactory.buildQueryFromWhereClause (m_EntityManager,l_QueryString, p_Clause);
		l_Activities = l_Query.getResultList();
		}
	catch (NoResultException p_Exception)
		{
		// Simply Return empty Collection
		}
	
	return l_Activities;
	}

//---------------------------------------------------------------------------
/**
 * Fetches invoice stubs matching the specified where clause.
 * @param p_Clause specifies the where clause that invoices have to match
 * in order to be taken into account.
 * @return A collection holding the matching invoice stubs, an empty collection 
 * if none are found.
 */
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <InvoiceStub> getInvoiceStubsByWhereClause (WhereClause p_Clause) throws Exception
	{
	Query						l_Query;
	String						l_QueryString;

	Collection <InvoiceStub>	l_InvoiceStubs;

	l_InvoiceStubs = new LinkedHashSet <InvoiceStub> ();
	
	if (p_Clause == null) return l_InvoiceStubs;

	l_QueryString = "SELECT OBJECT(o) FROM InvoiceStub o ";

	try	{
		l_Query = HibernateQueryFactory.buildQueryFromWhereClause (m_EntityManager,l_QueryString, p_Clause);
		l_InvoiceStubs = l_Query.getResultList();
		}
	catch (NoResultException p_Exception)
		{
		// Simply Return empty Collection
		}
	
	return l_InvoiceStubs;
	}


//---------------------------------------------------------------------------
/**
* Fetches all Acts for the given Patient, sorted newest first.
*/
//---------------------------------------------------------------------------

@RolesAllowed("gecam")
@SuppressWarnings("unchecked")
public Collection <Act> getActsForPatient (Patient p_Patient) throws Exception {
	List<Act> l_Acts = new ArrayList<Act>();
	try	{
		List<Invoice> l_Invoices = m_EntityManager.createNamedQuery (Invoice.c_InvoicesByPatient)
				   .setParameter("patient",p_Patient)
				   .getResultList();
		
		if (l_Invoices != null) {
			for (Invoice invoice : l_Invoices) {
				l_Acts.addAll(invoice.getActs());
			}			
		}
		Collections.sort(l_Acts, new Comparator<Act>() {
			public int compare(Act o1, Act o2) {
				try {
					return o2.getPerformedDate().compareTo(o1.getPerformedDate());					
				} catch (Exception e) {
					return 0;
				}
			}
		});
		
		return l_Acts;
		
	}	catch (NoResultException p_Exception) {
		
	}
	
	return null;
	}

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

}
