package songND.tws;

import javax.jws.WebService;
import javax.annotation.Resource;

import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.jbi.messaging.InOnly;
import javax.jbi.messaging.InOut;


import javax.annotation.Resource;
import javax.jws.WebService;
import javax.servlet.http.HttpSession;

import javax.xml.ws.Response;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.MessageContext;


import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import javax.naming.InitialContext;

import org.apache.log4j.Logger;
import org.apache.servicemix.MessageExchangeListener;
import org.apache.servicemix.components.util.ComponentSupport;

import org.apache.servicemix.jbi.jaxp.StringSource;
import org.apache.servicemix.jbi.jaxp.SourceTransformer;

import org.apache.servicemix.client.ClientFactory;
import org.apache.servicemix.client.Destination;
import org.apache.servicemix.client.ServiceMixClient;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.xml.transform.Source;

import javax.xml.transform.dom.DOMSource;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.servicemix.JbiConstants;


@WebService(targetNamespace = "http://myproject.com/NDTWS/" )

public class TargetWSImpl implements TargetWS{
	private final static Logger logger = Logger.getLogger(TargetWSImpl.class);

	private int myStatus = 0;

	private ServiceMixClient client = null; 
	
	private String operationName;
	
	private String stringReturnMessage;
	
	private int methodInvocationCorrelationId;
	
	public TargetWSImpl(){
		//logger.info("Target Costructor");
		client = createClient();
		methodInvocationCorrelationId = 0;
	}


 public boolean doLogin(String in0)throws Exception{ 

 	boolean returnValue = false;
 	
 	operationName= "doLogin";
			
	stringReturnMessage = invokeOperation(operationName, in0);
	
	methodInvocationCorrelationId++;
			
	returnValue = Boolean.parseBoolean(stringReturnMessage);
				
	return returnValue;	
 
 } 

 public String Listen(String in0)throws Exception{ 

 	String returnValue = "WS-Target-Listen internal error";

 	operationName= "Listen";
			
	stringReturnMessage = invokeOperation(operationName, in0);
	
	methodInvocationCorrelationId++;
		
	returnValue = stringReturnMessage; 
			
	return returnValue;
 } 

 public String SearchByTitle(String in0)throws Exception{ 

  	String returnValue = "WS-Target-SearchByTitle: internal error";

	operationName= "SearchByTitle";

	stringReturnMessage = invokeOperation(operationName, in0);
	
	methodInvocationCorrelationId++;
			
	returnValue = stringReturnMessage;

 	return returnValue;
 } 

 public String SearchByAuthor(String in0)throws Exception{ 
 	
 	String returnValue = "WS-Target-SearchByAuthor internal error";
	
	operationName= "SearchByAuthor";
 		
	stringReturnMessage = invokeOperation(operationName, in0);
	
	methodInvocationCorrelationId++;
			
	returnValue = stringReturnMessage;
			
	return returnValue;
 } 

 public int getStatus(){
 return myStatus;
 } 
 
private String invokeOperation(String operationName, String parameter){
	
	String stringReturnMessage = "internal_error";
	 
	try {
			Destination destination = client.createDestination("service:http://myproject.com/components/communicationManager");
			
			InOut inOutExchange = destination.createInOutExchange();

			NormalizedMessage message = inOutExchange.getInMessage();

            inOutExchange.setProperty(JbiConstants.CORRELATION_ID, "" + methodInvocationCorrelationId);
        
			String messageStringContent = 
			"<myMessage>" +	
				"<operationName>"+ operationName + "</operationName>" + 
				"<targetStatus>" + myStatus + "</targetStatus>" + 
				"<parameters>" +
					"<arg0>" + parameter + "</arg0>" +
				"</parameters>" +
			"</myMessage>";	
		
			logger.info("Target sends to CommunicationManager the following message : " + messageStringContent + "...");			

			inOutExchange.getInMessage().setContent(new StringSource(messageStringContent));
		
			client.sendSync(inOutExchange, 30000);
			//logger.info("... sendSync has timeout set to 30 sec ... ");	

			Source contentSource = null;
			try {
			contentSource = inOutExchange.getOutMessage().getContent();
			
			inOutExchange.setStatus(ExchangeStatus.DONE);
        	client.send(inOutExchange);	
        	//logger.info("status done");
				
			stringReturnMessage = new SourceTransformer().toString(contentSource);
			logger.info("Target receives from CommunicationManager the following message : " + stringReturnMessage);	
		
			DOMSource domSource = new SourceTransformer().toDOMSource(contentSource);
	
        	Node node = domSource.getNode();
		
			//responseForTarget
  			Node n1 = node.getFirstChild();
  			//if(n1.getNodeName().equals("responseForTarget"))
  			//{logger.info("responseForTarget");}
  		
  			//return
  			Node n2 = n1.getFirstChild();
			if(n2.getNodeName().equals("return"))
  			{
  				stringReturnMessage = n2.getTextContent(); 
  				logger.info("Web Service response : " + stringReturnMessage);
  			}	
  		
  			Node n3 = n2.getNextSibling();
  			if(n3.getNodeName().equals("successor")){
				myStatus = Integer.parseInt(n3.getTextContent()); 		
				logger.info("Target status has been modified : " + myStatus);
  			}
  			
		}
		catch(NullPointerException e) {
			logger.info("requested denied");
		}	
	}
	catch(Exception e) {
		e.printStackTrace();
	}
		
	return stringReturnMessage;
}
 
 private ServiceMixClient createClient() {
	try {
			ClientFactory factory = (ClientFactory) new InitialContext().lookup(ClientFactory.DEFAULT_JNDI_NAME);
			return factory.createClient();
			
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
	}
 
}