package cdac.medinfo.sdk.hl7282.hl7model;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import cdac.medinfo.sdk.hl7282.baselibs.messages.Message;
import cdac.medinfo.sdk.hl7282.baselibs.parserserializer.HL7Parser;
import cdac.medinfo.sdk.hl7282.baselibs.parserserializer.HL7Serializer;
import cdac.medinfo.sdk.hl7282.baselibs.segments.BHS;
import cdac.medinfo.sdk.hl7282.baselibs.segments.BTS;
import cdac.medinfo.sdk.hl7282.baselibs.segments.EVN;
import cdac.medinfo.sdk.hl7282.baselibs.segments.FHS;
import cdac.medinfo.sdk.hl7282.baselibs.segments.FTS;
import cdac.medinfo.sdk.hl7282.baselibs.segments.MSH;
import cdac.medinfo.sdk.hl7282.baselibs.segments.PID;
import cdac.medinfo.sdk.hl7282.baselibs.segments.PV1;
import cdac.medinfo.sdk.hl7282.commoninterface.ISegmentSet;
import cdac.medinfo.sdk.hl7282.commoninterface.ISingleCollection;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientadministration.ADTRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientadministration.ADT_A01;
import cdac.medinfo.sdk.hl7282.hl7net.auxiliaryprotocol.batch.BatchAgent;
import cdac.medinfo.sdk.hl7282.hl7net.auxiliaryprotocol.batch.HL7Batch;
import cdac.medinfo.sdk.hl7282.hl7net.auxiliaryprotocol.batch.HL7BatchFile;
import cdac.medinfo.sdk.hl7282.hl7net.commons.IBatchProcessor;
import cdac.medinfo.sdk.hl7282.hl7net.commons.IHL7Batch;
import cdac.medinfo.sdk.hl7282.hl7net.localextension.PopulateDataType;
import cdac.medinfo.sdk.hl7282.utils.EnumMessageCode;
import cdac.medinfo.sdk.hl7282.utils.EnumTriggerEvent;
import cdac.medinfo.sdk.hl7282.utils.HL7Config;
import cdac.medinfo.sdk.hl7282.utils.HL7Constants;
import cdac.medinfo.sdk.hl7282.utils.SingleCollection;

public class PopulateHL7BatchFile {
	private int MsgControlID = 0;
	String strMsgControlID =null;
	String strBatchControlID =null;
	public   static   void   main( String[] args ) 
	{ 
		//Specifying logging directory.
		//User can specify any directory where log files will be created.
		//If no path is specified then logs will be generated in user's temp directory.
		HL7Config.createInstance().enableLogging("E:\\HL7Model_Logs");

		PopulateHL7BatchFile objPopulateHL7BatchFile = new PopulateHL7BatchFile();
		objPopulateHL7BatchFile.start();
		
      
	}
	
	public void start() 
	{
		  HL7Serializer objHL7Serializer = null;
		   	
			/* 
			 * The HL7Parser parses the HL7Message and provides a SegmentSet.
			 * SegmentSet contains all segments of a HL7 Message in the same order as they appeared.
			 */
			ISegmentSet objSegmentSet = null;

			try
			{
				System.out.println("Enter file (.hl7 file) name to serialize Batch File of ADT_A01 Message Batch:   ");
				
				InputStreamReader input = new InputStreamReader(System.in);
				BufferedReader reader = new BufferedReader(input);
				
				String strHL7File = reader.readLine();
				
				//Populate Batch with ADT_A01 Messages		    	
			    	//create collection of messages. 
			    	ADT_A01 objADT_A01 = (ADT_A01)new ADTRecepient().createMessage(EnumMessageCode.ADT, EnumTriggerEvent.A01);
			    	populateMessage(objADT_A01);
			    	
			    	ADT_A01 objADT_A012 = (ADT_A01)new ADTRecepient().createMessage(EnumMessageCode.ADT, EnumTriggerEvent.A01);
			    	populateMessage(objADT_A012);
			    	
			    	ISingleCollection <Message> objMessageCollection = new SingleCollection <Message> (); 
			    	objMessageCollection.add(objADT_A01); 
			    	objMessageCollection.add(objADT_A012); 
			    	
			    	//Populate BHS and BTS Segments
			    	BHS objBatchHeader=populateBHS();
			    	BTS objBatchTrailer=populateBTS();
			    	
			    	HL7Batch objBatch = new HL7Batch(objBatchHeader,objBatchTrailer,objMessageCollection);
			    	
			    //Populate Batch1 with ADT_A01 Messages		    	
			    	//create collection of messages. 
			    	ADT_A01 objADT_A013 = (ADT_A01)new ADTRecepient().createMessage(EnumMessageCode.ADT, EnumTriggerEvent.A01);
			    	populateMessage(objADT_A013);
			    	
			    	ADT_A01 objADT_A014 = (ADT_A01)new ADTRecepient().createMessage(EnumMessageCode.ADT, EnumTriggerEvent.A01);
			    	populateMessage(objADT_A014);
			    	
			    	ISingleCollection <Message> objMessageCollection1 = new SingleCollection <Message> (); 
			    	objMessageCollection1.add(objADT_A013); 
			    	objMessageCollection1.add(objADT_A014); 
			    	
			    	//Populate BHS and BTS Segments
			    	BHS objBatchHeader1=populateBHS();
			    	BTS objBatchTrailer1=populateBTS();
			    	
			    	HL7Batch objBatch1 = new HL7Batch(objBatchHeader1,objBatchTrailer1,objMessageCollection1);
			    	//Add Batch to HL7 batch collection
					ISingleCollection<IHL7Batch> objHL7BatchCollection = new SingleCollection<>();
					objHL7BatchCollection.add(objBatch);
					objHL7BatchCollection.add(objBatch1);
					
					//Populate FHS and FTS Segments
					FHS objFHS=populateFHS();
					FTS objFTS=populateFTS();
					
					HL7BatchFile objBatchFile = new HL7BatchFile(objFHS, objFTS, objHL7BatchCollection);
			    	
			    	IBatchProcessor objbatchProcessor=new BatchAgent();
			    	objSegmentSet=objbatchProcessor.getSegmentSet(objBatchFile);
					
					objHL7Serializer = new HL7Serializer();
					objHL7Serializer.serialize(objSegmentSet,strHL7File);

					System.out.println("HL7 Batch File serialized successfully \n Stored at "+strHL7File);
				
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
					
	}

	public void populateMessage(ADT_A01 objADT_A01)  
	{ 
		
		MSH objMSH = populateMSH();
		objADT_A01.setHeader(objMSH);

		//EVN Segment
		EVN objEVN = populateEVN();
		objADT_A01.setEventTypeSegment(objEVN);

		//PID segment
		PID objPID = populatePID();
		objADT_A01.setPatientIdentificationSegment(objPID);
		//PV1 Segment
		PV1 objPV1 = populatePV1();
		objADT_A01.setPatientVisitSegment(objPV1);
	}

	private MSH populateMSH()
	{	
		strMsgControlID = "MSG010"+MsgControlID++;
		MSH objMSH = new MSH();
		objMSH.setFieldSeparator('|');//ST
		objMSH.setEncodingChars('^','&','~','\\','#');//ST
		objMSH.setDateTimeOfMessage("20000320");//TS
		objMSH.setMessageType("ADT","A01","ADT_A01");
		objMSH.setMessageControlID(strMsgControlID);//ST
		objMSH.setProcessingID("T", "T");//PT
		objMSH.setVersionID("2.8.2", null, null);//VID
		return objMSH;
	}
	
	public BHS populateBHS()
	{
		strBatchControlID="Batch123"+MsgControlID++;
		BHS objBatchHeader = new BHS(); 
	    objBatchHeader.setBatchFieldSeparator('|'); 
	    objBatchHeader.setBatchEncodingChars('^','&','~','\\','#');
	    objBatchHeader.setBatchControlID(strBatchControlID); 
	    	
	    return objBatchHeader;
	}

	public BTS populateBTS()
	{
		BTS objBatchTrailer = new BTS(); 
    	objBatchTrailer.addBatchTotals("2"); 
    	
    	return objBatchTrailer;
	}

	public FHS populateFHS()
	{
		FHS objFHS= new FHS();
    	objFHS.setFieldSeparator('|');
		objFHS.setEncodingChars('^','&','~','\\','#');
		return objFHS;
	}
	
	public FTS populateFTS()
	{
		FTS objFTS=new FTS();
		objFTS.setFileBatchCount("1");
		return objFTS;
	}
	/**
	 * populates EVN Segment
	 * @return EVN
	 */
	public EVN populateEVN()
	{
		//EVN segment
		EVN objEVN = new EVN();
		objEVN.setRecordedDateTime("20110202");//TS
		objEVN.setEventFacility(PopulateDataType.populateHD(HL7Constants.HL7_COMPONENT));
			return objEVN;
	}

	/**
	 * populates PID Segment
	 * @return PID
	 */
	public PID populatePID()
	{
		//PID Segment
		PID objPID = new PID();
		objPID.addPatientIdentifierList(PopulateDataType.populateCX(HL7Constants.HL7_COMPONENT));
		objPID.addPatientName(PopulateDataType.populateXPN(HL7Constants.HL7_COMPONENT));
		objPID.addPatientTelecommunicationInformation(PopulateDataType.populateXTN(HL7Constants.HL7_COMPONENT));
			return objPID;
	}


	/**
	 * populates PV1 Segment
	 * @return PV1
	 */
	public PV1 populatePV1()
	{

		//PV1 segment
		PV1 objPV1 = new PV1();
		objPV1.setSetID("02");
		objPV1.setPatientClass(PopulateDataType.populateCWE(HL7Constants.HL7_COMPONENT));
		objPV1.setServiceEpisodeIdentifier(PopulateDataType.populateCX(HL7Constants.HL7_COMPONENT));
		objPV1.setServiceEpisodeDescription("strServiceEpisodeDescription");
		return objPV1;
	}


}
