package net.ihe.xcpd.resp.action;

import java.io.IOException;
import java.util.GregorianCalendar;

import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.app.Connection;
import ca.uhn.hl7v2.app.ConnectionHub;
import ca.uhn.hl7v2.app.Initiator;
import ca.uhn.hl7v2.llp.LLPException;
import ca.uhn.hl7v2.llp.MinLowerLayerProtocol;
import ca.uhn.hl7v2.model.DataTypeException;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.model.primitive.CommonTS;
import ca.uhn.hl7v2.parser.EncodingNotSupportedException;
import ca.uhn.hl7v2.parser.Parser;
import ca.uhn.hl7v2.parser.PipeParser;


/**
 * @author abderrazek boufahja
 *
 */
public class PDCConnector {

	public int port = 3601;
	public String hostName = "localhost";
	
	public PDCConnector(){
	}

	public static String generateMessageString(String sendingApplication, 
												String sendingFacility, 
												String receivingApplication, 
												String receivingFacility, 
												String queryString, 
												int numberOfRowsToReturn, 
												String continuationPointer){
		String timeStamp=null;
		try {
			timeStamp = CommonTS.toHl7TSFormat(new GregorianCalendar());
		} catch (DataTypeException e) {
			e.printStackTrace();
		}
		System.out.println(timeStamp);
		String rr = "MSH|^~\\&|"+sendingApplication+"|"+sendingFacility+"|"+receivingApplication+"|"+receivingFacility+"|"+timeStamp+"||QBP^Q22|"+timeStamp+"|P|2.5||||||||\r" +
			"QPD|IHE PDQ Query|"+timeStamp+"|"+queryString+"\r" +
			"RCP|I|"+numberOfRowsToReturn+"^RD|||||\r";
		if (continuationPointer != null){
			if (!continuationPointer.equals("")){
				rr = rr + "DSC|" + continuationPointer + "|I\r";
			}
		}
		return rr;
	}
	
	public static String sendHl7Message(Message Msg, String targetHost, Integer targetPort){
		Parser parser = new PipeParser();
		Message response = null;
		try
		{
			ConnectionHub connectionHub = ConnectionHub.getInstance();
			Connection connection = connectionHub.attach(targetHost, targetPort, parser, MinLowerLayerProtocol.class);
			Initiator initiator = connection.getInitiator();
			response = initiator.sendAndReceive(Msg);
			connectionHub.detach(connection);
			//parser = new DefaultXMLParser();
			String responseString = parser.encode(response);
			return responseString ;
		}
		catch (HL7Exception e){
			e.getStackTrace();
			return e.getMessage();
		}
		catch (LLPException e)
		{
			e.printStackTrace();
			return e.getMessage();
		}
		catch (IOException e)
		{
			e.printStackTrace();
			return e.getMessage();
		}
	}

	public static Message  generateMessageToSend(String sendingApplication, String sendingFacility, String receivingApplication, String receivingFacility, String queryString, int numberOfRowsToReturn, String continuationPointer){
		Message Msg = null;
		String msgString = generateMessageString(sendingApplication, sendingFacility, receivingApplication, receivingFacility, queryString, numberOfRowsToReturn,continuationPointer);
		Parser parser = new PipeParser();
		try {
			Msg = parser.parse(msgString);
		} catch (EncodingNotSupportedException e) {
			e.printStackTrace();
		} catch (HL7Exception e) {
			e.printStackTrace();
		}
		return Msg;
	}

	public static String sendHl7Message(String sendingApplication, String sendingFacility,
										String receivingApplication, String receivingFacility,
										String queryString, int numberOfRowsToReturn,
										String targetHost, Integer targetPort, 
										String continuationPointer){
		Message msg = generateMessageToSend(sendingApplication, sendingFacility, receivingApplication, receivingFacility, queryString, numberOfRowsToReturn, continuationPointer);
		return sendHl7Message(msg, targetHost, targetPort);
	}

	public static String sendHl7Message(String msgString, String targetHost, Integer targetPort){
		Parser parser = new PipeParser();
		Message msg = null;
		try {
			msg = parser.parse(msgString);
		} catch (EncodingNotSupportedException e) {
			e.printStackTrace();
		} catch (HL7Exception e) {
			e.printStackTrace();
		}
		return sendHl7Message(msg, targetHost, targetPort);
	}
	
	public static Message string2Message(String ss){
		Message msgToSend = null;		
		try {
			Parser parser = new PipeParser();
			msgToSend = parser.parse(ss);
		} catch (HL7Exception e) {
			e.printStackTrace();
		}
		return msgToSend;
	}
	
	public static String sendHL7Message(String sendingApplication, String sendingFacility,
										String receivingApplication, String receivingFacility,
										String queryString, int numberOfRowsToReturn, 
										String targetHost, Integer targetPort, 
										String proxyHost, Integer proxyPort, 
										Boolean isSecured,String continuationPointer){
		if (proxyPort == null){
			return sendHl7Message(sendingApplication, sendingFacility, receivingApplication, receivingFacility, queryString, numberOfRowsToReturn, targetHost, targetPort, continuationPointer);
		}
		else{
			return sendHl7Message(sendingApplication, sendingFacility, receivingApplication, receivingFacility, queryString, numberOfRowsToReturn, proxyHost, proxyPort, continuationPointer);
		}
	}
}
