package com.ejie.p06b.ws;

import java.io.File;
import java.io.OutputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
//import weblogic.webservice.core.soap.SOAPElementImpl;
//import weblogic.webservice.core.soap.SOAPTextElement;



public class P06BWebServiceCall implements Serializable{
	private static final String HOST_PROXY_MAP="10.252.196.143";
	private static final String PORT_PROXY_MAP="8080";
	private static final boolean proxyUtili=false;
	//private static final boolean proxyUtili=true;
	
	private String sURL="";
	private String sMethod = "";
	public static final String iniCdata = "<![CDATA[";
	public static final String finCdata = "]]>";
	private static final String defStr = "";
	private static final String INI_TAG = "<";
	private static final String INI_END_TAG = "</";
	private static final String END_TAG = ">";
	
	private static final SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd"); 
	private static final SimpleDateFormat stf =
		new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 
	private static final SimpleDateFormat hour =
		new SimpleDateFormat ("HH:mm:ss"); 
	
	public P06BWebServiceCall (String sURL) {
        this.sURL = sURL;
    }
	
	private void inicializaConexion(){
		if(proxyUtili){
			java.util.Properties proxyConf = System.getProperties(); 
			proxyConf.setProperty("https.proxyHost", HOST_PROXY_MAP);
			proxyConf.setProperty("https.proxyPort", PORT_PROXY_MAP);
			System.setProperties(proxyConf);
		}
	}
	
	private void finalizaConexion(){
		if(proxyUtili){
			java.util.Properties proxyConf = System.getProperties(); 
			proxyConf.setProperty("https.proxyHost", "");
			proxyConf.setProperty("https.proxyPort", "");
			System.setProperties(proxyConf);
		}
	}
	
	public String invokeAppendRequest (String xmlContenedor){
		this.sMethod = "AppendRequest";
		String rtdo = "";
        try {     
        	inicializaConexion();
            MessageFactory mfactory = MessageFactory.newInstance();
            SOAPMessage message = mfactory.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPBody body = envelope.getBody();
             
            Name name = envelope.createName(this.sMethod, "", "http://www.openuri.org/");
            SOAPBodyElement element = body.addBodyElement(name);

            //TODO A descomentar para que funcione: Puesto para prueba local
            //SOAPElement param = element.addChildElement(envelope.createName("XMLRequest") );
            SOAPElement param = element.addChildElement(envelope.createName("string") );
            param.addTextNode(xmlContenedor);
                
            SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
            SOAPConnection con = factory.createConnection();
            SOAPMessage response = con.call(message, this.sURL);

            rtdo = getResultado(response);
        }catch (Exception e) {
            e.printStackTrace();
         }finally{
        	finalizaConexion();
        }        
        return rtdo;
    }
	
	public String initializeFileRequest (String instanceId, String fileName, boolean overwrite){
		this.sMethod = "InitializeFile";
		String rtdo = "";
        try {     
        	inicializaConexion();
            MessageFactory mfactory = MessageFactory.newInstance();
            SOAPMessage message = mfactory.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPBody body = envelope.getBody();
            
            Name name = envelope.createName(this.sMethod, "", "http://www.openuri.org/");
            SOAPBodyElement element = body.addBodyElement(name);
            //TODO A descomentar para que funcione: Puesto para prueba local
            //SOAPElement param = element.addChildElement(envelope.createName("InstanceId") );
            SOAPElement param = element.addChildElement(envelope.createName("string") );
            
            param.addTextNode(instanceId);
            
            //TODO A descomentar para que funcione: Puesto para prueba local            
            //SOAPElement param2 = element.addChildElement(envelope.createName("FileName") );
            SOAPElement param2 = element.addChildElement(envelope.createName("string0") );
            
            param2.addTextNode(fileName);
           
            //TODO A descomentar para que funcione: Puesto para prueba local                
            //SOAPElement param3 = element.addChildElement(envelope.createName("Overwrite") );
            SOAPElement param3 = element.addChildElement(envelope.createName("string1") );
            
            param3.addTextNode(overwrite+"");
            
            SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
            SOAPConnection con = factory.createConnection();
            SOAPMessage response = con.call(message, this.sURL);

            rtdo = getResultado(response);
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
        	finalizaConexion();
        }        
        return rtdo;
    }
	
	public String removeInstanceRequest (String instanceId){
		this.sMethod = "RemoveInstance";
		String rtdo = "";
        try {     
        	inicializaConexion();
            MessageFactory mfactory = MessageFactory.newInstance();
            SOAPMessage message = mfactory.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPBody body = envelope.getBody();
            
            Name name = envelope.createName(this.sMethod, "", "http://www.openuri.org/");
            SOAPBodyElement element = body.addBodyElement(name);

            //TODO A descomentar para que funcione: Puesto para prueba local            
            //SOAPElement param = element.addChildElement(envelope.createName("InstanceId") );
            SOAPElement param = element.addChildElement(envelope.createName("string") );
            param.addTextNode(instanceId);

            SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
            SOAPConnection con = factory.createConnection();
            SOAPMessage response = con.call(message, this.sURL);

            rtdo = getResultado(response);
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
        	finalizaConexion();
        }        
        return rtdo;
    }
	
	public String appendChunkRequest (String instanceId, Long offset, Integer bufferSize, String data){
		this.sMethod = "AppendChunk";
		String rtdo = "";
		String fileTmpName = "\\datos\\p06b\\tmp\\tmpFile_"+new Date().getTime()+".xml";
		try {     
        	inicializaConexion();
            MessageFactory mfactory = MessageFactory.newInstance();
            SOAPMessage message = mfactory.createMessage();
            SOAPPart soapPart = message.getSOAPPart();
            SOAPEnvelope envelope = soapPart.getEnvelope();
            SOAPBody body = envelope.getBody();
            //Asociamos al header content-type del mensaje soap el valor dime para indicarle
            //el tipo de encapsulamiento del mensaje del attach que meteremos ahora
            message.getMimeHeaders().setHeader(
					"content-type","application/dime");
            
            //Vas metiendo bloques de 128k
            //Opcion1 
            /*AttachmentPart attachFile1 = message.createAttachmentPart(data.getBytes(),"application/binary");
            message.addAttachmentPart(attachFile1);*/
            
            //Opcion2 => Parece la buena
            FileDataSource file = new FileDataSource(fileTmpName);
            OutputStream outFile = file.getOutputStream();
            outFile.write(data.getBytes());
            DataHandler handlerFile = new DataHandler(file);
            AttachmentPart attachFile = message.createAttachmentPart(handlerFile);                 
            message.addAttachmentPart(attachFile);
            outFile.close();

            Name name = envelope.createName(this.sMethod, "", "http://www.openuri.org/");
            SOAPBodyElement element = body.addBodyElement(name);
            
            //TODO A descomentar para que funcione: Puesto para prueba local 
            //SOAPElement param = element.addChildElement(envelope.createName("InstanceId") );
            SOAPElement param = element.addChildElement(envelope.createName("string") );
            param.addTextNode(instanceId);
            
            //TODO A descomentar para que funcione: Puesto para prueba local            
            //SOAPElement param2 = element.addChildElement(envelope.createName("Offset") );
            SOAPElement param2 = element.addChildElement(envelope.createName("string0") );
            param2.addTextNode(offset.toString());
            
            //TODO A descomentar para que funcione: Puesto para prueba local            
            //SOAPElement param3 = element.addChildElement(envelope.createName("BufferSize") );
            SOAPElement param3 = element.addChildElement(envelope.createName("string1") );         
            param3.addTextNode(bufferSize.toString());
            
            SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
            SOAPConnection con = factory.createConnection();
            SOAPMessage response = con.call(message, this.sURL);
            			
            rtdo = getResultado(response);
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
        	finalizaConexion();
        	//Elimino el fichero fuente
            new File(fileTmpName).delete();
        }        
        return rtdo;
    }
	
    private static SOAPBodyElement getSOAPBodyElement (SOAPMessage response) throws SOAPException {
        SOAPBodyElement rtdo = null;
        Iterator iterator = response.getSOAPPart().getEnvelope().getBody().getChildElements();

        while (iterator.hasNext()) {
            Object oUndefined = iterator.next();
            if (oUndefined instanceof SOAPBodyElement) {
                rtdo = (SOAPBodyElement) oUndefined;
                break;
            }
        }
        return rtdo;
    }

 
    public static String getResultado (SOAPMessage response) throws SOAPException {
        String rtdo = "";
        String masRtdo = "";
        SOAPBodyElement soapBodyElement = getSOAPBodyElement(response);
        String responseElementName = soapBodyElement.getElementName().toString();
        if(!responseElementName.equalsIgnoreCase("env:Fault"))
        {
	        //String resultElementName = responseElementName.replaceAll("Response$", "Result");
        	String resultElementName = "result";
        	Iterator iterator = soapBodyElement.getChildElements();
	
	        while (iterator.hasNext()) {
	            SOAPElement element = (SOAPElement) iterator.next();
	            String elementName = element.getElementName().toString();
	            if (elementName.equals(resultElementName)) {
	                // el element es el elemento resultado.
	                rtdo = element.getValue();
	                break;
	            }
	        }  
        }
        else
        {
        	rtdo = "Fallo:";
	    	//Recoger el fallo que viene dentro de la etiqueta faultstring y mandarlo en rtdo
	    	Iterator iterator = soapBodyElement.getChildElements();
	    	 
	        while (iterator.hasNext()) {
	        	
	        	Object objeto = iterator.next();
	        	Class clase = objeto.getClass();
	        	String nombreClase = clase.toString();
	        	if(nombreClase.equals("class weblogic.webservice.core.soap.SOAPElementImpl"))
	        	{
	        		/*SOAPElementImpl element = (SOAPElementImpl) objeto;
		            String elementName = element.getElementName().toString();
		            if (elementName.equals("faultstring")) 
		            {
		            	Iterator hijos = element.getChildren();
		    	        while (hijos.hasNext())
		    	        {		    	        	
		    	        	Object objetoHijo = hijos.next();
		    	        	SOAPTextElement texto = (SOAPTextElement)objetoHijo;
	    	        		String texto1 = texto.toString();
	    	        		if(texto1.indexOf("</>")!=-1) texto1 = texto1.substring(0,texto1.indexOf("</>"));
	    	        		masRtdo += texto1;
		    	        }
		                rtdo += masRtdo;
		                break;
		            }*/	        		
	        	}	        	
	        } 
        }
        return rtdo;
    }    
}
