package cdac.medinfo.sdk.hl7282.tool.hl7editor;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;

import cdac.medinfo.sdk.hl7282.baselibs.messages.Message;
import cdac.medinfo.sdk.hl7282.baselibs.messages.MessageFactory;
import cdac.medinfo.sdk.hl7282.baselibs.parserserializer.HL7Parser;
import cdac.medinfo.sdk.hl7282.baselibs.segments.MSH;
import cdac.medinfo.sdk.hl7282.baselibs.segments.Segment;
import cdac.medinfo.sdk.hl7282.commoninterface.IDelimiter;
import cdac.medinfo.sdk.hl7282.commoninterface.ISegment;
import cdac.medinfo.sdk.hl7282.commoninterface.ISegmentKey;
import cdac.medinfo.sdk.hl7282.commoninterface.ISegmentSet;
import cdac.medinfo.sdk.hl7282.commoninterface.ISingleCollection;
import cdac.medinfo.sdk.hl7282.exceptions.DelimiterMissingException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidDataTypeException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidDelimiterException;
import cdac.medinfo.sdk.hl7282.exceptions.InvalidMessageException;
import cdac.medinfo.sdk.hl7282.exceptions.ParseException;
import cdac.medinfo.sdk.hl7282.hl7model.messages.applicationmanagement.AppMgtRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.applicationmanagement.AppMgtSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.clinicallaboratoryautomation.ClinicalLabAutoRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.clinicallaboratoryautomation.ClinicalLabAutoSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.financialmanagement.FinancialRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.financialmanagement.FinancialSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.masterfiles.MasterFileRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.masterfiles.MasterFileSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.medicalrecords.MediRecRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.medicalrecords.MediRecSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.observationreporting.ObsvRepRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.observationreporting.ObsvRepSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.orderentry.OrderEntryRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.orderentry.OrderEntrySource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientadministration.ADTRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientadministration.ADTSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientcare.PatientCareRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientcare.PatientCareSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientreferral.PatientRefRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.patientreferral.PatientRefSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.personnelmanagement.PersonalMgmtRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.personnelmanagement.PersonalMgmtSource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.query.QryRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.query.QrySource;
import cdac.medinfo.sdk.hl7282.hl7model.messages.scheduling.SchedulingRecepient;
import cdac.medinfo.sdk.hl7282.hl7model.messages.scheduling.SchedulingSource;
import cdac.medinfo.sdk.hl7282.hl7streams.HL7BufferStream;
import cdac.medinfo.sdk.hl7282.hl7streams.HL7FileStream;
import cdac.medinfo.sdk.hl7282.utils.EnumSegments;
import cdac.medinfo.sdk.hl7282.utils.HL7Config;
import cdac.medinfo.sdk.hl7282.utils.HL7Constants;
import cdac.medinfo.sdk.hl7282.utils.HL7Exception;
import cdac.medinfo.sdk.hl7282.utils.HL7Logger;
import cdac.medinfo.sdk.hl7282.utils.MultiValuedPairedCollection;
import cdac.medinfo.sdk.hl7282.utils.ResourceBundleWrapper;
import cdac.medinfo.sdk.hl7282.utils.SingleCollection;

public class HL7Editor 
{
	static int lengthOfOption = 20;
	static int lengthOfDetails = 80 - lengthOfOption;

	private static HL7FileStream objIHL7Stream;
	private File objFileWrite;
	private FileOutputStream objFileOutputStream;


	public static void main(String[] args)
	{
		String strLoggingPath = null;
		String isForecefullyRemove = "f";

		HL7Editor objHL7Editor = new HL7Editor();

		String strHL7File = null;

		String strDestFolder = null;

		ISingleCollection<String> objRemoveSegInfoCollection = new SingleCollection<String>();

		ISingleCollection<String> objRemoveSegAttributeInfoCollection = new SingleCollection<String>();

		ISingleCollection<String> objUpdateSegAttributeInfoCollection = new SingleCollection<String>();

		/*
		 * If no parameters are provided then display the help.
		 */
		if(args == null || args.length == 0)
		{
			objHL7Editor.displayHelp();
			System.exit(0);
		}

		/*
		 * This loop initializes the service parameters from the arguments provided.
		 */
		for(int i=0; i<args.length; i++)
		{
			//logging path.
			if(args[i].equalsIgnoreCase("-d") && args.length > i+1)
			{
				strLoggingPath = args[i+1];
				i++;
			}

			//isForecefullyRemove.
			else if(args[i].equalsIgnoreCase("-i") && args.length > i+1)
			{
				isForecefullyRemove = args[i+1];
				i++;
			}

			// dump folder
			else if(args[i].equalsIgnoreCase("-s") && args.length > i+1)
			{
				//reading destination dir path where received requests will be dumped
				strDestFolder = args[i+1] ;
				i++;
			}

			//HL7 File
			else if(args[i].equalsIgnoreCase("-f") && args.length > i+1)
			{
				strHL7File = args[i+1] ;
				i++;
			}

			//Remove Segment Attribute
			else if(args[i].equalsIgnoreCase("-a") && args.length > i+1)
			{
				String strtagInfo = args[i+1] ;
				objRemoveSegAttributeInfoCollection.add(strtagInfo);
				i++;
			}
			//Remove Segment
			else if(args[i].equalsIgnoreCase("-e") && args.length > i+1)
			{
				String strRemoveSegInfo = args[i+1] ;
				objRemoveSegInfoCollection.add(strRemoveSegInfo);
				i++;
			}
			//Update Segment Attribute
			else if(args[i].equalsIgnoreCase("-u") && args.length > i+1)
			{
				String strUpdateSegInfo = args[i+1] ;
				objUpdateSegAttributeInfoCollection.add(strUpdateSegInfo);
				i++;
			}
			else
			{
				System.out.println("Not a valid command");
				objHL7Editor.displayHelp();
				System.exit(0);
			}
		}


		// Validate Command
		if(strHL7File == null)
		{
			System.out.println("Not a valid command");
			objHL7Editor.displayHelp();
			System.exit(0);
		}

		if(!isForecefullyRemove.equalsIgnoreCase("f") && !isForecefullyRemove.equalsIgnoreCase("t"))
		{
			System.out.println("Not a valid Command.Wrong option specified for -i. The vale can be F(false) or T(true)");
			objHL7Editor.displayHelp();
			System.exit(0);
		}

		if(objRemoveSegInfoCollection.size() > 0 && objRemoveSegAttributeInfoCollection.size() > 0 )
		{
			System.out.println("Not a valid Command.At once only segment/group or segment attribute can be removed ");
			objHL7Editor.displayHelp();
			System.exit(0);
		}

		if(objRemoveSegInfoCollection.size() == 0 && objRemoveSegAttributeInfoCollection.size() == 0 && objUpdateSegAttributeInfoCollection.size() == 0)
		{
			System.out.println("Specify atleast one option to remove or update.");
			objHL7Editor.displayHelp();
			System.exit(0);
		}

		if(strDestFolder == null)
		{
			strDestFolder = System.getProperty("java.io.tmpdir")+"/CDAC-SDK/HL7-J/HL7Editor/";
		}

		if(strLoggingPath == null)
		{
			strLoggingPath = System.getProperty("java.io.tmpdir")+"/CDAC-SDK/HL7-J/Logs/";
		}

		HL7Config objHL7Config = HL7Config.createInstance();

		//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.
		objHL7Config.enableLogging(strLoggingPath);

		// Create Message
		Message objMessage = objHL7Editor.createMessageAndDump(strHL7File, strDestFolder);
		if(objMessage == null)
		{
			System.out.println("Message creation failed...");
			objHL7Editor.displayHelp();
			System.exit(0);
		}

		int iResult = HL7Constants.HL7_FUNCTION_FAIL;
		boolean bForce = false;
		if(isForecefullyRemove.equalsIgnoreCase("t"))
			bForce = true;

		MSH objMsh = objMessage.getHeader();
		IDelimiter objDelimiter = objMsh.getDelimiter();

		try
		{
			// REMOVE SEGMENT OR GROUP
			if(objRemoveSegInfoCollection.size() > 0)
			{
				iResult = objHL7Editor.removeSegments(objMessage,objRemoveSegInfoCollection, bForce);

			}
			// REMOVE SEGMENT ATTRIBUTE
			if(objRemoveSegAttributeInfoCollection.size() > 0)
			{
				iResult = objHL7Editor.removeSegmentAttribute(objMessage,objRemoveSegAttributeInfoCollection, bForce);
			}
			// UPDATE ATTRIBUTE IF PRESENT OTHERWISE ADD.
			if(objUpdateSegAttributeInfoCollection.size() > 0)
			{
				iResult = objHL7Editor.updateSegmentAttribute(objMessage, objUpdateSegAttributeInfoCollection, objDelimiter);
			}

			if(iResult == HL7Constants.HL7_FUNCTION_SUCCESS)
			{
				//HL7Serializer objSerializer = new HL7Serializer();
				//objSerializer.serialize(objMessage.getSegmentSet(), strHL7File);
				//HL7FileStream objStream = new HL7FileStream();
				//objStream.setOutputStream(new FileOutputStream("D:\\1.doc"));

				objMessage.dumpMessage(objIHL7Stream);
				System.out.println("\nHL7 message edited successfully. \n");
				System.out.println("\nDump of HL7 message is stored at " + strDestFolder + "\n");
			}
			else
			{
				objMessage.dumpMessage(objIHL7Stream);
				System.out.println("\nHL7 message not edited successfully. Please refer log at the path " + strLoggingPath + "\n");
				System.out.println("\nDump of HL7 message is stored at " + strDestFolder + "\n");
			}
		}
		catch(Exception e)
		{
			System.out.println("HL7 file edition failed........");
			e.printStackTrace();
		}
	}

	/**
	 * Removes Segment Attributes.
	 * @param objMessage Object of Message
	 * @param objRemoveSegAttributeInfoCollection Collection of segment attributes to be removed.
	 * @param force Boolean value True - for removing attribute forcefully.
	 * @return integer value of HL7Constants foe success or failure.
	 */
	private int removeSegmentAttribute(Message objMessage, ISingleCollection<String> objRemoveSegAttributeInfoCollection, boolean force)
	{
		MultiValuedPairedCollection<ISegmentKey, Integer> objSegmentKeyCollection = new MultiValuedPairedCollection<ISegmentKey, Integer>();
		int iResult = HL7Constants.HL7_FUNCTION_SUCCESS;
		try
		{
			for(String strRemoveSegAttributeInfo : objRemoveSegAttributeInfoCollection)
			{
				if(strRemoveSegAttributeInfo.contains(":"))
				{
					String[] arraySeg_ItemID = strRemoveSegAttributeInfo.split(":");
					if(arraySeg_ItemID.length!=2)
						throw new HL7Exception(ResourceBundleWrapper.getValue("exceptions", "InvalidInputsForAttributeRemoval", new Locale(HL7Config.createInstance().getLocale())));
					String strSegment = arraySeg_ItemID[0];
					String strItemID = arraySeg_ItemID[1];
					int iItemID = Integer.parseInt(strItemID);

					ISegmentKey objSegmentKey  = null;
					if(strSegment != null || strSegment != "")
					{
						String strPrefix = "HL7_SEG_";
						objSegmentKey  = EnumSegments.valueOf(strPrefix + strSegment);
						objSegmentKeyCollection.put(objSegmentKey, iItemID);
					}
				}
			}
			if(objSegmentKeyCollection != null)
			{
				iResult = objMessage.removeSegmentAttribute(objSegmentKeyCollection , force);
			}
			return iResult;
		}
		catch(IllegalArgumentException iae)
		{
			System.out.println("Invalid Segment Name........");
			System.out.println("HL7 file edition failed........");
			iae.printStackTrace();
			return HL7Constants.HL7_FUNCTION_FAIL;
		}
	}


	/**
	 * Removes segments fron HL7 message
	 * @param objMessage Object of Message
	 * @param objRemoveSegInfoCollection Collection of segments to be removed.
	 * @param bForce Boolean value True - for removing attribute forcefully.
	 * @return integer value of HL7Constants foe success or failure.
	 */
	private int removeSegments(Message objMessage,ISingleCollection<String> objRemoveSegInfoCollection,boolean bForce)
	{
		ISingleCollection<ISegmentKey> objRemoveSegKeyCollection = new SingleCollection<ISegmentKey>();
		try
		{	
			for(String strRemoveSegmentName : objRemoveSegInfoCollection)
			{
				if(strRemoveSegmentName != null && (strRemoveSegmentName.equalsIgnoreCase("MSH") || strRemoveSegmentName.equalsIgnoreCase("FHS") || strRemoveSegmentName.equalsIgnoreCase("BHS")))
				{
					System.out.println("HL7 Header can not be remove from the HL7 file");
				}
				else if(strRemoveSegmentName != null || strRemoveSegmentName != "")
				{
					String strPrefix = null;
					if(strRemoveSegmentName.length() == 3) // if Segment
						strPrefix = "HL7_SEG_";
					else								// if Group
						strPrefix = "HL7_GROUP_";

					ISegmentKey objSegmentKey  = EnumSegments.valueOf(strPrefix + strRemoveSegmentName);
					objRemoveSegKeyCollection.add(objSegmentKey);
				}
			}
			int iResult = removeSegmentOrGroup(objMessage,objRemoveSegKeyCollection,bForce);
			return iResult;
		}
		catch(IllegalArgumentException iae)
		{
			System.out.println("Invalid Segment Name........");
			System.out.println("HL7 file edition failed........");
			iae.printStackTrace();
			return HL7Constants.HL7_FUNCTION_FAIL;
		}
	}

	/**
	 * Populate message from given HL7 file.
	 * @param strHL7File String value for absolute path of HL7 file.
	 * @param strDestinationPath String value for Destination folder to which HL7 file dump in the form of MS doc will be stored.
	 * @return Object of Message.
	 */
	private Message createMessageAndDump(String strHL7File, String strDestinationPath)
	{
		Message objMessage = null;
		try
		{
			HL7Parser objParser = new HL7Parser();
			ISegmentSet objSegmentSet = objParser.parse(strHL7File);

			ISegment objSegment = objSegmentSet.getSegment(0);
			String strSegment = objSegment.getName().getValue();
			strSegment = strSegment.trim();

			if(strSegment.equals(EnumSegments.HL7_SEG_MSH.getValue()))
			{
				String strMessageCode =null;
				String strTriggerEvent = null;
				Segment objTempSegment = (Segment)objSegmentSet.getSegment(0);
				if(objTempSegment.getName().equals(EnumSegments.HL7_SEG_MSH))
				{
					MSH objMSH = (MSH)objTempSegment;
					strMessageCode = (String)objMSH.getMessageType().getMessageCode().getValue();
					strTriggerEvent = (String)objMSH.getMessageType().getTriggerEvent().getValue();
				}
				objMessage = getMessage(strMessageCode, strTriggerEvent, objSegmentSet);

				getFileForDump(strTriggerEvent, strMessageCode, strDestinationPath, "Original");

				//dump original Message
				objMessage.dumpMessage(objIHL7Stream);

				getFileForDump(strTriggerEvent, strMessageCode, strDestinationPath, null);
			}
			else
			{
				System.out.println("\nOperation supported for HL7 messages only. ");
			}
		}
		catch(ParseException pe)
		{

			if(HL7Config.createInstance().isLoggingOn())
			{
				HL7Logger.getLogger().log(pe);
			}
			pe.printStackTrace();
		}
		catch (InvalidMessageException e) 
		{
			if(HL7Config.createInstance().isLoggingOn())
			{
				HL7Logger.getLogger().log(e);
			}
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			if(HL7Config.createInstance().isLoggingOn())
			{
				HL7Logger.getLogger().log(e);
			}
			e.printStackTrace();
		}
		return objMessage;
	}

	/**
	 * Creates the MS document fo HL7 file.
	 * @param strHL7File HL7 File path.
	 * @param strDestinationPath  Destination folder to store created document.
	 */
	private int removeSegmentOrGroup(Message objMessage, ISingleCollection<ISegmentKey> objRemoveSegKeyCollection, boolean isForecefullyRemove)
	{
		int iResult = HL7Constants.HL7_FUNCTION_FAIL;
		int cnt = 0;
		//Call Remove
		if(objMessage != null)
		{
			if(objRemoveSegKeyCollection != null && objRemoveSegKeyCollection.size() >0)
			{
				for(ISegmentKey key : objRemoveSegKeyCollection)
				{
					iResult = objMessage.removeSegment(key, isForecefullyRemove);
					if(iResult == HL7Constants.HL7_FUNCTION_SUCCESS)
					{
						System.out.println("HL7 message edited for : " + key.getValue());
					}
					else
					{
						cnt = 1;
						System.out.println("HL7 message can not be edited for : " + key.getValue());
					}
				}
			}
		}
		if(cnt == 1) 
			return HL7Constants.HL7_FUNCTION_FAIL;
		else
			return iResult;
	}

	/*
	 * Populates message through provided SegmentSet,MessageCode and TriggerEvent
	 */
	private Message getMessage(String strMessageCode,String strTriggerEvent,ISegmentSet objSegmentSet)
	{
		Message objMessage = null;

		MessageFactory objMessageFactory = getMessageFactory();

		objMessage = objMessageFactory.populateReceiveSupportedMessage(strMessageCode, strTriggerEvent, objSegmentSet);

		if(objMessage != null)
		{
			objMessage = objMessageFactory.createSendSupportedMessage(strMessageCode, strTriggerEvent);
			if(objMessage != null)
				objMessage.populate(objSegmentSet);
		}

		return objMessage;
	}

	/*
	 * Populates Message Factory
	 */
	private MessageFactory getMessageFactory()
	{
		MessageFactory objMessageFactory = MessageFactory.createInstance();

		objMessageFactory.addMessageSource(new ObsvRepSource());
		objMessageFactory.addMessageRecepient(new ObsvRepRecepient());
		objMessageFactory.addMessageSource(new AppMgtSource());
		objMessageFactory.addMessageRecepient(new AppMgtRecepient());
		objMessageFactory.addMessageSource(new ClinicalLabAutoSource());
		objMessageFactory.addMessageRecepient(new ClinicalLabAutoRecepient());
		objMessageFactory.addMessageSource(new FinancialSource());
		objMessageFactory.addMessageRecepient(new FinancialRecepient());
		objMessageFactory.addMessageSource(new MasterFileSource());
		objMessageFactory.addMessageRecepient(new MasterFileRecepient());
		objMessageFactory.addMessageSource(new MediRecSource());
		objMessageFactory.addMessageRecepient(new MediRecRecepient());
		objMessageFactory.addMessageSource(new OrderEntrySource());
		objMessageFactory.addMessageRecepient(new OrderEntryRecepient());
		objMessageFactory.addMessageSource(new ADTSource());
		objMessageFactory.addMessageRecepient(new ADTRecepient());
		objMessageFactory.addMessageSource(new PatientCareSource());
		objMessageFactory.addMessageRecepient(new PatientCareRecepient());
		objMessageFactory.addMessageSource(new PatientRefSource());
		objMessageFactory.addMessageRecepient(new PatientRefRecepient());
		objMessageFactory.addMessageSource(new PersonalMgmtSource());
		objMessageFactory.addMessageRecepient(new PersonalMgmtRecepient());
		objMessageFactory.addMessageSource(new QrySource());
		objMessageFactory.addMessageRecepient(new QryRecepient());
		objMessageFactory.addMessageSource(new SchedulingSource());
		objMessageFactory.addMessageRecepient(new SchedulingRecepient());

		return objMessageFactory;
	}

	/*
	 * This function displays the help.
	 */
	private void displayHelp()
	{
		//Description of command
		System.out.println("\nHL7EDITOR :: Editor tool edits the HL7 file. This tool can add or remove the \nSegment or Group." +
		"Also can update the Attribute of a segment in HL7 file if \npresent or add if segment structure has that attribute.");

		//Signature
		System.out.println("\n" + "HL7EDITOR [-d LogDir] " +
				" -f HL7File [-e \"SegmentOrGroupName\"] [-i f] [-a \"SegName:ItemID\"] [-u \"SegName:ItemID:Value\"]" 
				+ " [-s DestinationFolder]  " + "\n");

		//Log directory
		printToConsole("-d", "Log directory");
		printToConsole("", "User's temp directory is taken as default.");

		//HL7 Files
		printToConsole("-f", "HL7 File which is to be updated.");

		//Remove Segment or Group 
		printToConsole("-e", "Segment name which is to be removed to the file.");
		printToConsole("", "For eg -> -e EVN");

		//isForecefullyRemove
		printToConsole("-i", "Segment or Group removes fourcefully if value is true.");
		String [] arrisForecefullyRemove = {"F False","T True"};
		printToConsole("IsFourcefullyRemove", arrisForecefullyRemove);
		printToConsole("","Default IsFourcefullyRemove is False(F).");

		printToConsole("-a", "Remove Segment Attribute");
		printToConsole("", "For eg -> -a EVN:100");

		printToConsole("-u", "Update Segment Attribute if Attribute is present or add the");
		printToConsole("","attribute if segment structure has that attribute.");
		printToConsole("", "For eg -> -u PID:106:NewValue");

		// Storage path
		printToConsole("-s", "Destination folder path to store converted MS documet file.");
		printToConsole("", "User's temp directory is taken as default.");
		
        
        System.out.println("\nExample :");

		//Example
		System.out.println("\n1. HL7EDITOR -f message.hl7 -e EVN -e PID" +
		"\nEdit the HL7 file message.hl7. Removes segment EVN, PID from the HL7 file.\n");

		//Example
		System.out.println("\n2. HL7EDITOR -f message.hl7 -a EVN:100" +
		"\nEdit the HL7 file message.hl7. Removes attribute recordeddatetime from segment \nEVN of HL7 file.\n");

		//Example
		System.out.println("\n3. HL7EDITOR -f message.hl7 -u PID:106:newValue" +
		"\nEdit the HL7 file message.hl7. Update attribute having 106 as Item ID from \nsegment PID to the new value newValue." +
		"The attribute will be modified if present otherwise this will get added to the segment PID if structure of PID has that \nattribute.\n");

	
	}

	/**
	 * Display Help of command on console in proper manner.
	 * @param strOption Option for command.
	 * @param strDetails Description of option.
	 */
	public static void printToConsole(String strOption, String strDetails)
	{
		String strBuffer = "";
		if (strOption != null)
			strBuffer = strBuffer + strOption ;
		while (lengthOfOption > strBuffer.length())
		{
			strBuffer = strBuffer + " ";
		}
		if (strDetails != null)
		{
			if (strDetails.length() < lengthOfDetails || strDetails.length() == lengthOfDetails)
			{
				strBuffer = strBuffer + strDetails;
				strDetails = null;
			}
			else
			{
				strBuffer = strBuffer + strDetails.substring(0, lengthOfDetails);
				strDetails = strDetails.substring(lengthOfDetails, (strDetails.length() ));
			}
		}

		System.out.println(strBuffer);
		if (strDetails == null)
			return;
		else
			printToConsole(null, strDetails);
	}

	/**
	 * Display Help of command on console in proper manner.
	 * @param strAttribute Attribute for option.
	 * @param strDesc Description of attributes.
	 */
	public static void printToConsole(String strAttribute, String[] strDesc)
	{
		if (strDesc.length > 1)
			printToConsole(strAttribute, strDesc[0]);
		for(int i = 1;i<strDesc.length;i++)
			printToConsole(null, strDesc[i]);
	}

	/**
	 * Updates the attribute of segment if present, otherwise add it if segment structure has that attribute.
	 * @param objMessage Object of Message
	 * @param objUpdateSegAttributeInfoCollection Collection of Attribute information.
	 * @param objDelimiter Object of IDelimiter
	 * @return 
	 */
	private int updateSegmentAttribute(Message objMessage,ISingleCollection<String> objUpdateSegAttributeInfoCollection, IDelimiter objDelimiter)
	{
		int iResult = HL7Constants.HL7_FUNCTION_FAIL;
		try
		{
			for(String strUpdateSegAttributeInfo : objUpdateSegAttributeInfoCollection)
			{
				if(strUpdateSegAttributeInfo.contains(":"))
				{
					String[] arraySeg_ItemID = strUpdateSegAttributeInfo.split(":");
					if(arraySeg_ItemID.length!=3)
						throw new HL7Exception(ResourceBundleWrapper.getValue("exceptions", "InvalidInputsForAttributeUpdate", new Locale(HL7Config.createInstance().getLocale())));
					String strSegment = arraySeg_ItemID[0];
					String strItemID = arraySeg_ItemID[1];
					String strAttributeValue = arraySeg_ItemID[2];

					int iItemID = Integer.parseInt(strItemID);

					ISegmentKey objSegmentKey  = null;
					if(strSegment != null || strSegment != "")
					{
						String strPrefix = "HL7_SEG_";
						objSegmentKey  = EnumSegments.valueOf(strPrefix + strSegment);
						iResult = objMessage.updateSegmentAttribute(objSegmentKey, iItemID, strAttributeValue, objDelimiter);
						if(iResult == HL7Constants.HL7_FUNCTION_FAIL)
							break; 
					}
				}
			}
			return iResult;
		}
		catch(IllegalArgumentException iae)
		{
			System.out.println("Invalid Segment Name........");
			System.out.println("HL7 file edition failed........");
			iae.printStackTrace();
			return HL7Constants.HL7_FUNCTION_FAIL;
		} 
		catch (DelimiterMissingException e)
		{
			e.printStackTrace();
			return HL7Constants.HL7_FUNCTION_FAIL;
		}
		catch (InvalidDelimiterException e)
		{
			e.printStackTrace();
			return HL7Constants.HL7_FUNCTION_FAIL;
		}
		catch (InvalidDataTypeException e)
		{
			e.printStackTrace();
			return HL7Constants.HL7_FUNCTION_FAIL;
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return HL7Constants.HL7_FUNCTION_FAIL;
		}   
	}

	/**
	 * Generates file for dumping
	 * @param strTriggerEvent String value for TriggerEvent
	 * @param strMessageCode String value for MessageCode
	 * @param strDestinationPath String value Destination Dolder Path
	 */
	private void getFileForDump(String strTriggerEvent,String strMessageCode, String strDestinationPath, String strPrefix)
	{
		objIHL7Stream = new HL7FileStream();
		try
		{
			File testDir =  new File(strDestinationPath);
			testDir.mkdir();
			String strPathForDump = null;

			if(strPrefix != null)
				strPathForDump = strDestinationPath + "\\" + strPrefix + "_" + strMessageCode+"_"+strTriggerEvent+".doc";
			else
				strPathForDump = strDestinationPath + "\\" +strMessageCode+"_"+strTriggerEvent+".doc";

			objFileWrite = new File(strPathForDump);
			objFileWrite.createNewFile();
			objFileOutputStream = new FileOutputStream(objFileWrite);	
			objIHL7Stream.setOutputStream(objFileOutputStream);
		}
		catch(IOException ioe)
		{
			ioe.printStackTrace();
		}
	}
}
