/*
 * NIST HL7 Web Service
 * MessageGenerationUtils.java May 19, 2008
 *
 * This code was produced by the National Institute of Standards and
 * Technology (NIST). See the "nist.disclaimer" file given in the distribution
 * for information on the use and redistribution of this software.
 */

package gov.nist.hl7.ws.messagegeneration;

import gov.nist.hl7.core.MalformedProfileException;
import gov.nist.hl7.core.message.AbstractMessage;
import gov.nist.hl7.core.message.XmlMessage;
import gov.nist.hl7.core.profile.Profile;

import gov.nist.hl7.core.validation.message.TableProfileDocument;
import gov.nist.hl7.core.validation.message.TableProfileDocument.TableProfile;
import gov.nist.hl7.core.validation.message.TableProfileDocument.TableProfile.TableDefinition;
import gov.nist.hl7.ws.JdbcRepositoryDao;
//import gov.nist.hl7.ws.Logger;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
//import java.util.logging.Level;
//import java.util.logging.Logger;
import javax.xml.transform.TransformerFactoryConfigurationError;
import org.apache.xmlbeans.XmlException;
import gov.nist.hl7.core.generation.simple.SimpleMessageGeneration;
import gov.nist.hl7.core.generation.simple.SimpleMessageGenerationContextDocument;
import org.apache.log4j.Logger;

/**
 * 
 * @author Harold AFFO (NIST)
 * 
 */
public class MessageGenerationUtils { 
   private static Logger log=Logger.getLogger(MessageGenerationUtils.class);
   
	//private static final Logger _logger = Logger.getLogger(MessageGenerationUtils.class.getCanonicalName());

	public synchronized SimpleMessageGenerationContextDocument getSimpleMessageGenerationContext(String xmlGenerationContext) throws XmlException, IOException {
	   log.info("Hl7MessageGenerationInterface - User sets a message generation context");
		SimpleMessageGenerationContextDocument smgc = SimpleMessageGenerationContextDocument.Factory.parse(xmlGenerationContext);
		return smgc;
	}
/**
 * 
 * @param aProfile
 * @param aSimpleMessageGenerationContextDocument
 * @return
 * @throws TransformerFactoryConfigurationError
 * @throws Exception
 */
	 public synchronized AbstractMessage generate(Profile aProfile,SimpleMessageGenerationContextDocument aSimpleMessageGenerationContextDocument, TableProfileDocument resource)
			throws TransformerFactoryConfigurationError, Exception {
            
	    SimpleMessageGeneration smg = new SimpleMessageGeneration();  
		AbstractMessage resultat =null;
		
        if (aProfile != null && aSimpleMessageGenerationContextDocument != null){
           log.info("Hl7MessageGenerationInterface - User runs Message generation");
        	 XmlMessage xmlMessage = null; 
        	if(resource !=null)     	 
        	   xmlMessage=  smg.generateMax(aProfile,resource,3);
			 else
			   xmlMessage = smg.generateMax(aProfile,3);   	  
        	resultat = smg.generate(aProfile, xmlMessage, aSimpleMessageGenerationContextDocument);
        }
		 return resultat ; 
	}
	 	  
	 
		
	/**
	 * 
	 * @param profileStr
	 * @return
	 * @throws Exception
	 */
	public synchronized Profile getProfile(String profileStr) throws Exception {
 		Profile profile = null ; 
		if (profileStr.length() > 2 * 1024 * 1024) {
 			throw new Exception("File is too large (Max Size=2MB)");
		}
		//logger.log(Level.INFO,"HL7MessageGenerationInterface - User sets a profile with no id ");
		log.info("HL7MessageGenerationInterface - User sets a profile");
		profile = new Profile("", profileStr);
		return profile ; 
	}

	/**
	 * 
	 * @param encoding
	 * @return
	 * @throws Exception 
	 */

	public  synchronized String getMessage(AbstractMessage resultats) throws Exception {		
		if( resultats !=null) 
            return resultats.toString(); 
		else 
			throw new Exception("No message is generated."); 
	}
	
	/**
	 * 
	 * @param handleOID
	 * @param rDao
	 * @return
	 * @throws SQLException
	 * @throws MalformedProfileException
	 * @throws XmlException
	 */

	 public synchronized Map<String, Object> useHandle(String handleOID, JdbcRepositoryDao rDao) throws SQLException, MalformedProfileException, XmlException {
	        String [] bindings = rDao.getBindings(handleOID);
	        TableProfileDocument tempResource = TableProfileDocument.Factory.newInstance();
	        TableProfile tables = tempResource.addNewTableProfile();
	        TableProfileDocument curResource = null ; 
	        int blength = bindings.length;
	        if (blength > 1) {
	            // map to the resource
	            //TableType [] tt = new TableType [blength -1];
	            // [0] is the profile OID
	            for (int i = 1; i < blength; i++) {
	            	curResource = rDao.getResource(bindings[i]);
	                // add the current resource to the main object.
	                List<TableDefinition> curTableList = curResource.getTableProfile().getTableDefinitionList();
	                //.getTables().getTableList();
	                tables.setTableDefinitionArray(curTableList.toArray(new TableDefinition[curTableList.size()]));
	                //tables.setTableArray(curTableList.toArray(new TableType[curTableList.size()]));
	            } 
	            tempResource = curResource ; 
	            
	        } else {
	            throw new SQLException("This handle cannot be used for the generation.");
	        } 
	               
	        Map<String, Object> map = new HashMap<String, Object>();
	        //map.put("resource", rDao.getResource(bindings[1]));
	        map.put("resource",tempResource);
	        map.put("profile", rDao.getProfile(bindings[0]));
	        return map;
	    } 
	 
	public synchronized void clear(Profile profile , AbstractMessage message , SimpleMessageGenerationContextDocument smgContext,String exception , TableProfileDocument resource){
		 profile = null ; 
		 message = null;
		 smgContext = null;
		 exception = null;
		 resource  = null ; 
		 System.gc(); 
	}

}
