/*
 * This file is part of DebGen Biobank Software developed by ASTRID Research.
 * All rights reserved. Reproduction, modification, use or disclosure
 * to third parties without express authority is forbidden.
 *
 * Copyright ASTRID Research Inc., Hungary, 2009-2011.
 *
 * ASTRID Research
 * Headquaters: Csapo utca 42. Debrecen H-4029 HUNGARY
 * Phone: +36-52-533-173        Fax: +36-52-533-174
 * Web: http://www.astrid.hu    E-mail: info@astrid.hu
 *
 * Project name: DebGen Biobank Software project.
 * URLS:
 * Developers: Istvan Zoltan Nagy (istvan.nagy@astrid.hu)
 */
package hu.astrid.debgen.patientmanagement.service.modules.requests;

import hu.astrid.debgen.patientmanagement.domain.modules.requests.AnalysisRequest;
import hu.astrid.shared.server.service.BaseOperationsAbstract;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

/**
 * The Service, which is handling the Analysis Requests
 * @author inagy
 */
public class RequestManagerService extends BaseOperationsAbstract {

    /**
     * Returns an instance of a AnalysisRequestCommonManagerService and sets its session.
     * @param session The session os the Service to use the DB connection.
     * @return A new instance.
     */
    public static BaseOperationsAbstract getInstance(Session session) {
        RequestManagerService requestManagerService = new RequestManagerService();
        requestManagerService.session = session;
        return requestManagerService;
    }

    /**
     * Loads the AnalysisRequest by the given id
     * @param id The id of the AnalysisRequest
     * @return The AnalysisRequest object with the specified id (if there is such thing)
     */
    public AnalysisRequest load(Long id) {
        return super.load(AnalysisRequest.class, id);
    }

    /**
     * Returns a list of AnalysisRequestCommons
     * @param order The ordering attribute to order the results ascending
     * @param offset The index of the first result entry.
     * @param length The number of elements on one page
     * @return The list of records on the current page.
     */
    public List<AnalysisRequest> list(String order, int offset, int length) {
        return this.find(null, order, offset, length);
    }

    /**
     * Finds the matching AnalysisRequest(s) using the criterias
     * @param what The search criterias
     * @param order The ordering attribute to order the results ascending
     * @param offset The index of the first result entry.
     * @param length The number of elements on one page
     * @return The list of records on the current page.
     */
    public List<AnalysisRequest> find(AnalysisRequest what, String order, int offset, int length) {
        Criteria criteria = session.createCriteria(AnalysisRequest.class);
        List list = criteria.addOrder(Order.asc(order)).setFirstResult(offset).setMaxResults(length).list();
        List<AnalysisRequest> AnalysisRequestCommons = new ArrayList<AnalysisRequest>(length);
        if (list != null && !list.isEmpty()) {
            for (Object o : list) {
                AnalysisRequestCommons.add((AnalysisRequest) o);
            }
        }
        return AnalysisRequestCommons;
    }

    /**
     * Deletes the given analysisrequest objects record from the DB
     * @param analysisRequestCommon The AnalysisRequest which should be deleted
     */
    public void delete(AnalysisRequest analysisRequestCommon) {
        session.delete(analysisRequestCommon);
    }

    /**
     * Returns the number of matching AnalysisRequest records
     * @param all Include all AnalysisRequestCommons?
     * @return The number of matching AnalysisRequestCommons
     */
    public double countList() {
        return this.countSearchList(null);
    }

    /**
     * Returns the number of matching AnalysisRequest records
     * @param what The search criterias.
     * @return The number of matching AnalysisRequest
     */
    public double countSearchList(AnalysisRequest what) {
        Criteria criteria = session.createCriteria(AnalysisRequest.class);
        Object result = criteria.setProjection(Projections.countDistinct("id")).uniqueResult();
        return Double.parseDouble(result.toString());
    }

    /**
     * Lists all data of the given String type attribute from the AnalysisRequest class
     * @param clazz The persistens class, which contains the field.
     * @param field The name of the field.
     * @param query The pattern which should match in START MatchMode
     * @return The list of matching attribute values
     */
    public List<String> listField(Class clazz, String field, String query) {
        Criteria criteria = session.createCriteria(clazz).add(Restrictions.like(field, query, MatchMode.START));
        List list = criteria.addOrder(Order.asc(field)).list();
        ArrayList<String> result = new ArrayList<String>(list.size() + 1);
        for (Object o : list) {
            try {
                String value = (String) clazz.getMethod("get" + field.substring(0, 1).toUpperCase() + field.substring(1)).invoke((AnalysisRequest) o);
                if (!result.contains(value)) {
                    result.add(value);
                }
            } catch (IllegalAccessException ex) {
                //IGNORED
            } catch (IllegalArgumentException ex) {
                //IGNORED
            } catch (InvocationTargetException ex) {
                //IGNORED
            } catch (NoSuchMethodException ex) {
                //IGNORED
            } catch (SecurityException ex) {
                //IGNORED
            }
        }
        return result;
    }
}
