package gov.va.med.esr.webservices.client;

import gov.va.med.esr.mvc.model.GetEESummaryRequest;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.xml.soap.SOAPMessage;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.WebServiceMessageCallback;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.security.xwss.XwsSecuritySecurementException;

import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSecurityException;

/**
 * Client for JAX-WS Web Service.
 * @author Trinadh Kavuri
 *
 */
public class SpringWSClient {

	private static XWSSProcessor cprocessor;

	private static ProcessingContext context;

	private WebServiceTemplate webServiceTemplate;

	// send to the configured default URI
	public static void main(String[] args) {

		setCerts();
		ApplicationContext appContext = new ClassPathXmlApplicationContext(
				"/client/applicationContext-client.xml");
		SpringWSClient client = (SpringWSClient) appContext
				.getBean("springWSClient");
		try {
			client.customSendAndReceive();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// send to an explicit URI
	public void customSendAndReceive() throws Exception {

		GetEESummaryRequest request = new GetEESummaryRequest();
		//request.setKey("0000002000000624V902523000000");
		//request.setKey("0000001003700359V2811360001000");
		request.setKey("0000000000000000V889286000000");
		                
		request.setRequestName("request_financials_only");
		Resource xwssConfig = new ClassPathResource("/client/wss-client-config.xml");
		if (!xwssConfig.exists()) {
			throw new FileNotFoundException();
		}

		XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();
		cprocessor = factory.createProcessorForSecurityConfiguration(xwssConfig
				.getInputStream(), null);
		context = new ProcessingContext();

		Object resultObj = getWebServiceTemplate().marshalSendAndReceive(
				request, new WebServiceMessageCallback() {
					public void doWithMessage(WebServiceMessage message)
							throws IOException {
						// We can cast safley to SaajSoapMessage   
						SaajSoapMessage saajSoapMessage = (SaajSoapMessage) message;
						SOAPMessage saajMessage = saajSoapMessage
								.getSaajMessage();
						try {
							context.setSOAPMessage(saajMessage);
							SOAPMessage securedMessage = cprocessor
									.secureOutboundMessage(context);
							saajSoapMessage.setSaajMessage(securedMessage);
						} catch (XWSSecurityException e) {
							throw new XwsSecuritySecurementException(e
									.getMessage());
						}
					}
				});

		//StreamResult result = new StreamResult(System.out);
		//Object resultObj = webServiceTemplate.marshalSendAndReceive(request);
		System.out.println("resultObj:" + resultObj);
	}

	public WebServiceTemplate getWebServiceTemplate() {
		return webServiceTemplate;
	}

	public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) {
		this.webServiceTemplate = webServiceTemplate;
	}

	private static void setCerts() {
		System.out.println("trustStore :"
				+ System.getProperty("javax.net.ssl.trustStore"));
		if (System.getProperty("javax.net.ssl.trustStore") == null) {
			//String trustStoreName = System.getProperty("trustStoreName",
			//		"jssecacerts");
			//String trustStorePassword = System.getProperty(
			//		"javax.net.ssl.trustStorePassword", "changeit");

			//String trustStoreName = "jssecacerts";
			String trustStoreName = "D:/bea/projects/ESR.3.0.0/DNS   kavurt_HECMS_Websrv_1/vobs/HECMS_websrv/jssecacerts";

			trustStoreName = trustStoreName.replace('/', File.separatorChar);
			String trustStorePassword = "changeit";

			System.out.println("trustStoreName :" + trustStoreName);
			String detectedAbsolutePath = trustStoreName;

			//String detectedAbsolutePath = ClassLoader.getSystemResource(
			//		trustStoreName).getFile(); // assumes classpath can find it
			System
					.setProperty("javax.net.ssl.trustStore",
							detectedAbsolutePath);
			System.setProperty("javax.net.ssl.trustStorePassword",
					trustStorePassword);
			/**
			System.setProperty("javax.net.debug",
					"all");
			**/
		}

	}

}
