package lu.tudor.santec.gecamed.esante.ejb.session.interfaces;

import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lu.tudor.santec.gecamed.esante.ejb.entity.beans.CdaCode;
import lu.tudor.santec.gecamed.esante.ejb.entity.beans.CdaCodeCategory;
import lu.tudor.santec.gecamed.esante.ejb.entity.beans.CdaCodeDescription;
import lu.tudor.santec.gecamed.esante.ejb.entity.beans.ESanteLogin;
import lu.tudor.santec.gecamed.esante.ejb.entity.beans.ESanteProperty;

/**
 * @author jens.ferring(at)tudor.lu
 * 
 * @version <br>
 *          $Log: ESanteConfigManager.java,v $
 *          Revision 1.15  2014-02-04 10:08:42  ferring
 *          eSante ID management completed
 *          Only those documents will be shown, that are retrieved by the RSQ
 *
 *          Revision 1.14  2014-01-29 16:57:51  donak
 *          Renamed references to HPD to eHealth in respect to the request of the eHealth Agency
 *          Removed template DSP-11-12 as it is not needed and was created only for internal testing purposes
 *
 *          Revision 1.13  2014-01-28 16:02:44  ferring
 *          eHealth ID management implemented
 *
 *          Revision 1.12  2014-01-27 13:13:47  donak
 *          * Properties are now saved in db in respect to the following contexts:
 *            - specific to a GECAMed user
 *            - specific to a GECAMed physician
 *            - specific to an eSanté plattform user
 *            - general (independend of GECAMed user, physician, eSanté platform user)
 *          * Improved authentication handling. A signed authentication request is now only done for user authentication. for dsp authentication requests the provided saml assertion is used. (authentication speed up). ATTENTION: This fix is currently disabled till a bug in the eSanté platform has been fixed.
 *          * Naming of message loggings had been adapted to the naming in the connection kit (e.g. DSP-10, DSP-22)
 *          * Changed behavior for handling of dsps for which physician has insufficient access permissions. If physician does not want to provide presence password, a DSP-11 is sent instead of a DSP-12 to allow the physician to at least access the documents he is author of.
 * <br>
 *          Revision 1.11 2014-01-21 14:32:05 ferring <br>
 *          myDSP configuration can be changed and reloaded. <br>
 *          The clean CDA files on server function was added <br>
 * <br>
 *          Revision 1.10 2013-12-09 17:15:37 donak <br>
 *          Bug-fixing for upload to eSanté platform <br>
 *          Revision 1.9 2013-12-04 15:22:34 ferring <br>
 *          CdaCodeDescription added <br>
 * <br>
 *          Revision 1.8 2013-12-04 13:12:52 ferring <br>
 *          CdaCodeDescription added <br>
 * <br>
 *          Revision 1.7 2013-11-12 12:48:23 donak <br>
 *          Document upload: <br>
 *          * conversion to pdf/a using open office has been moved to the server. OpenOffice 4 has to be located in the jboss work directory. ATTENTION: it
 *          still has to be evaluated if the license agreement dialog occurs when instance is started the first time on the server. <br>
 *          * If document contains a description, the first forty characters of the description followed by three dots will be used as title instead of the
 *          filename <br>
 *          * Upload of incident type letters has been fixed <br>
 *          * upload for docx files has been added <br>
 * <br>
 *          Upload parameters: <br>
 *          * database does now support storage of user dependent properties <br>
 *          * The system will automatically remember the last chosen values for confidentiality, facility type, and speciality and propose them as default when
 *          the next document will be uploaded. <br>
 * <br>
 *          Inactivity Monitor: <br>
 *          * the event mouse wheel scrolling is now taken into account for resetting the logoff timer <br>
 *          * the logoff delay is now stored in the database. If the database does not contain this parameter, it will be created <br>
 * <br>
 *          General: <br>
 *          * Optimized incident entry bean handling. Caching will now avoid copying the binary content and the generated pdf content of an incident entry as
 *          these elements should only be loaded when needed. Now it should be save to re-implement a proper getBinaryContent() handling. <br>
 * <br>
 *          Revision 1.6 2013-10-21 08:14:26 ferring <br>
 *          loading CdaCodes if there not loaded and creating not existing, if they don't exist in the DB <br>
 * <br>
 *          Revision 1.5 2013-10-08 08:57:36 ferring <br>
 *          commit comments utf8 correction <br>
 * <br>
 *          Revision 1.4 2013-10-03 11:17:21 donak <br>
 *          eSanté integration CDA document upload metadata configuration dialog <br>
 * <br>
 *          Revision 1.3 2013-10-01 10:03:11 ferring <br>
 *          enhancement in code fetching <br>
 * <br>
 *          Revision 1.2 2013-09-19 12:24:43 ferring <br>
 *          eSante bugs fixed and documents stored in database <br>
 * <br>
 *          Revision 1.1 2013-09-13 14:18:56 ferring <br>
 *          eSante bugs fixed and database implementation started <br>
 */

public interface ESanteConfigManager {
	/**
	 * Retrieves the value of the eSanté parameter with that name.
	 * 
	 * @param name
	 *            The name of the eSanté parameter to get.
	 * @return The value of the eSanté parameter with the given name.
	 */
	public String getESantePropertyValue (String name);
	
	/**
	 * Retrieves the eSanté parameter with that name.
	 * 
	 * @param name
	 *            The name of the eSanté parameter to get.
	 * @return The eSanté parameter with the given name.
	 */
	public ESanteProperty getESanteProperty (String name);
	
	/**
	 * Retrieves an user-specific parameter
	 * 
	 * @param name
	 *            The name of the eSanté parameter to get.
	 * @param userId
	 *            The id of the user to whom this parameter has been assigned.
	 * @return The eSanté parameter with the given name.
	 */
	public String getUserProperty(String name, Integer userId);

	/**
	 * Retrieves an physician-specific parameter
	 * 
	 * @param name
	 *            The name of the eSanté parameter to get.
	 * @param physicianId
	 *            The id of the physician to whom this parameter has been assigned.
	 * @return The eSanté parameter with the given name.
	 */
	public String getPhysicianProperty(String name, Integer physicianId);

	/**
	 * Retrieves an eSanté user-specific parameter. An eSanté user is usually identified via a smartcard or login password
	 * 
	 * @param name
	 *            The name of the eSanté parameter to get.
	 * @param esanteUserId
	 *            The id of the eSanté user to whom this parameter has been assigned. The deSanté user id is usually the id of the smartcard of the eSanté user
	 *            of the id the user has to provide when entering the login/password
	 * @return The eSanté parameter with the given name.
	 */
	public String getESanteUserProperty(String name, String esanteUserId);
	
	/**
	 * @param name The property name
	 * @return A List of all ESanteProperties, with the specified name and 
	 * 	where the ESante user ID is not <code>null</code>. 
	 */
	public List<ESanteProperty> getESanteUserProperties (String name);

	/**
	 * @return All eSanté property-value-pairs in a map.
	 */
	public Map<String, String> getESanteProperties();

	/**
	 * @param nameLike Search criteria for the property names.
	 * @return All eSanté property-value-pairs whose name fits to the nameLike in a map.
	 */
	public Map<String, String> getESanteProperties (String nameLike);
	
	/**
	 * Define a new or update an existing eSanté parameter.
	 * 
	 * @param name
	 *            The name of the parameter
	 * @param value
	 *            The string value of the parameter
	 */
	public ESanteProperty setESanteProperty(String name, String value);
	
	/**
	 * Takes the properties and merges them into the DB.
	 * 
	 * @param properties The properties to change
	 * @return The saved properties
	 */
	public List<ESanteProperty> saveESanteProperties (Collection<ESanteProperty> properties);
	
	/**
	 * Deletes all these properties in the database.
	 * 
	 * @param properties The properties to delete
	 */
	public void deleteProperties (Collection<ESanteProperty> properties);

	/**
	 * Define a new or update an existing GECAMed-user-specific eSanté parameter.
	 * 
	 * @param name
	 *            The name of the parameter
	 * @param userId
	 *            The id of the GECAMed user to whom this parameter has been assigned.
	 * @param value
	 *            The string value of the parameter
	 */
	public ESanteProperty setUserProperty(String name, String value, Integer userId);

	/**
	 * Define a new or update an existing physician-specific eSanté parameter.
	 * 
	 * @param name
	 *            The name of the parameter
	 * @param userId
	 *            The id of the physician to whom this parameter has been assigned.
	 * @param value
	 *            The string value of the parameter
	 */
	public ESanteProperty setPhysicianProperty(String name, String value, Integer physicianId);

	/**
	 * Define a new or update an existing eSanté-user-specific eSanté parameter.
	 * 
	 * @param name
	 *            The name of the parameter
	 * @param value
	 *            The string value of the parameter
	 * @param esanteUserId
	 *            The id of the eSanté platform user to whom this parameter has been assigned. The deSanté user id is usually the id of the smartcard of the
	 *            eSanté user of the id the user has to provide when entering the login/password
	 */
	public ESanteProperty setESanteUserProperty(String name, String value, String esanteUserId);

	/**
	 * Saves all key value pairs of the given HashMap into the database where the ID is <code>null</code>.
	 * 
	 * @param properties The properties to save.
	 */
	public void setESanteProperties (HashMap<String, String> properties);
	
	/**
	 * @param physicianId
	 *            The physician ID to return the login for
	 * @return The login information for the referred physician
	 */
	public ESanteLogin getESanteLogin(Integer physicianId);

	/**
	 * Adds or updates the given ESanteLogin object in the databse.
	 * 
	 * @param login
	 *            The login to store.
	 * @return The stored login.
	 */
	public ESanteLogin saveESanteLogin(ESanteLogin login);

	/**
	 * Provides a list of all CDA codes that are children of the node with the provided id
	 * 
	 * @param parentId
	 *            The parentId to search for.
	 * @return All {@link CdaCode} with the specified parentId.
	 */
	public List<CdaCode> getCdaCodeChildren(Integer parentId);

	/**
	 * @param categoryId
	 *            The category ID to search for
	 * @param codeId
	 *            The codeId to search for
	 * @param descriptionLanguage
	 *            The language to get the description
	 * @return The {@link CdaCode} with the specified category and code id
	 */
	public CdaCode getCdaCode(Integer categoryId, String codeId, String descriptionLanguage);

	/**
	 * @param uuid
	 *            The UUID to query for the CdaCodeCategory.
	 * @return The {@link CdaCodeCategory} with the specified UUID
	 */
	public CdaCodeCategory getCategoryByUuid(String uuid);

	/**
	 * @param name
	 *            The name to query for the CdaCodeCategory.
	 * @return The {@link CdaCodeCategory} with the specified name
	 */
	public CdaCodeCategory getCategoryByName(String name);

	/**
	 * @param codeId
	 *            The primary key of the CdaCode bean.
	 * @param language
	 *            The description language
	 * @return The CdaCodeDescription for the code with the specified ID in the specified language
	 */
	public CdaCodeDescription getCdaCodeDescription(Integer codeId, String language);

	/**
	 * @param codeCategoryId
	 *            The ID of the CdaCodeCategory
	 * @param language
	 *            The description language
	 * @return All CdaCodeDescriptions in the specified language of the specified CdaCodeCategory
	 */
	public Map<Integer, CdaCodeDescription> getCdaCodeDescriptionsOfCategory(Integer codeCategoryId, String language);

	/**
	 * @param codeIdList
	 *            The IDs of the CdaCodes to fetch.
	 * @param language
	 *            The description language
	 * @return A Map with the CdaCode ID as key and its display name as value.
	 */
	public Map<Integer, String> getCdaCodeDescription(Collection<Integer> codeIdList, String language);

	/**
	 * Creates a new CdaCode with the given information and stores it in the database.
	 * 
	 * @param categoryId
	 *            The categoryId of the CdaCode
	 * @param codeId
	 *            The codeId of the CdaCode
	 * @param codeOid
	 *            The OID of the CdaCode in the repository
	 * @param displayName
	 *            The displayName of the CdaCode
	 * @param description
	 *            The description of the CdaCode
	 * @param language
	 *            The language of the displayName and description
	 * @param parentId
	 *            The parentId of the CdaCode
	 * @return The stored CdaCode
	 */
	public CdaCode saveCdaCode(Integer categoryId, String codeId, String codeOid, String displayName, String description, String language, Integer parentId);

	/**
	 * Creates a new CdaCodeDescription with the given information and stores it in the database.
	 * 
	 * @param codeId
	 *            The id of the CdaCode this description belongs to
	 * @param displayName
	 *            The displayName of the CdaCode
	 * @param description
	 *            The description of the CdaCode
	 * @param language
	 *            The language of the displayName and description
	 * @return The stored CdaCodeDescription
	 */
	public CdaCodeDescription saveCdaCodeDescription(Integer codeId, String displayName, String description, String language);
	
	/**
	 * If there the specified eSanté template files is stored on the server, it is returned 
	 * (it is search for a template valid for todays date).
	 * If not, null is returned and you need to take the default template from
	 * the GECAMed-Client JAR (/lu/tudor/santec/gecamed/esante/resources/templates/).
	 * 
	 * @param templateName The file name of the template
	 * @return The UTF-8 formatted file as byte array.
	 */
	public byte[] loadTemplateFile (String templateName);
	
	/**
	 * Stores the template with the given data in the given file.
	 * If the applicabilityDate is in the past, the date will be
	 * applied directly (like the date was <code>null</code>). 
	 * 
	 * @param templateName The file name to store the template
	 * @param templateData The file data to store in the template
	 * @param applicabilityDate The date, from which on this template shall be used 
	 * or null, if it shall be used from now on.
	 * @return Whether or not the file could have been saved.
	 */
	public boolean saveTemplateFile (String templateName, byte[] templateData, Date applicabilityDate);

	/**
	 * Loads all WSDL templates for today.
	 * 
	 * @return all WSDL templates for today
	 */
	public HashMap<String, String> loadTemplateFiles (String[] templateNames);
	
	/**
	 * deletes all esante properties for the user identified by the given eSanteUserId
	 * @param eHealthUserId
	 * @throws Exception
	 */
	public void deleteESanteUser(String eSanteUserId) throws Exception;

	public void deletePracticeEhealthID();
	
	public void installOpenOffice(boolean deleteBefore) throws Exception;
	
	public String checkOpenOffice();
}
