/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package bugaath;

import conexionlimbo.ConexionLimbo;
import java.io.StringWriter;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import javax.xml.ws.handler.Handler;

/**
 *
 * @author Flia Moreno Rivera
 */
public class BugaAth {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       
        BugaAth p= new BugaAth();
       consultaResponse.IFX pru=  p.consultarFacturaPorNumero("123456789","20010190000832");
       
       // System.out.println(pru.getPresSvcRs().getBillInqRs().getStatus().getStatusCode());
       // p.registrarPagoIFX("123456789","20010190000832","22300000");
       // p.reverso("123456789","20010390023962","2700000");
     
    }
    public void disableSslVerification() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    @Override
                    public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
            };
            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HostnameVerifier allHostsValid = (String hostname, SSLSession session) -> true;
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
        }
    }
    
       public consultaResponse.IFX consultarFacturaPorNumero(String Rqid,String referencia)  {
           disableSslVerification();
        
        javax.xml.ws.Holder<java.lang.String> cadenaIFX = null;
        consultaResponse.IFX rsp = null;
        try { 
        consultaRequest.IFX strIFX =new consultaRequest.IFX(Rqid,referencia);
        
        
        JAXBContext contextObj = JAXBContext.newInstance(consultaRequest.IFX.class);
            
        StringWriter stringWriter = new StringWriter();
        Marshaller marshallerObj = contextObj.createMarshaller();
        marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            
        marshallerObj.marshal(strIFX, stringWriter);
            //  System.out.println(stringWriter.toString());
        String cadena = stringWriter.toString();
        
        Holder<String> holderxml = createParam(cadena); 
        athbugaifx.PSServiciosRecaudoService service = new athbugaifx.PSServiciosRecaudoService();
        athbugaifx.PSServiciosRecaudoBinding port = service.getPSServiciosRecaudoBinding();
         System.out.println("wsdl " + service.getWSDLDocumentLocation());
        
       
            BindingProvider bindingProvider = (BindingProvider) port;
            List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
            handlerChain.add(new HandlerTrama());
            bindingProvider.getBinding().setHandlerChain(handlerChain);
            Map<String, Object> requestContext = bindingProvider.getRequestContext();
            requestContext.put("com.sun.xml.internal.ws.request.timeout", 3000);

            Instant durationStart = Instant.now();
            port.consultarFacturaPorNumero(holderxml);
            
             rsp = new consultaResponse.IFX(holderxml.value);
            
            Instant durationEnd = Instant.now();
            Duration duration = Duration.between(durationStart, durationEnd);

            Map<String, String> result = processRequest(bindingProvider, duration.toMillis(),referencia,"consultarFacturaPorNumeroATH");
        } catch (Exception e) {
             Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            if (e.getMessage().contains("timed out")) {
                System.out.println("timed out popayan consultarFacturaPorNumero");
                Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            } else {
                System.out.println("Error ws popayan consultarFacturaPorNumero");
                Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            }
        }
        return rsp;

    }

     protected static Holder<String> createParam(String value) {
        Holder<String> param = new Holder<>();
        param.value = value;
        return param;
    }
    protected Map<String, String> processRequest(BindingProvider bindingProvider, long duracion,String referencia,String consumo) {
        Map<String, Object> responseContext = bindingProvider.getResponseContext();
        String requestBody = (String) responseContext.get("com.realtech.request");
        String responseBody = (String) responseContext.get("com.realtech.response");

        requestBody = requestBody.replace("&lt;", "<");
        requestBody = requestBody.replace("&gt;", ">");

        responseBody = responseBody.replace("&lt;", "<");
        responseBody = responseBody.replace("&gt;", ">");

        Map<String, String> trama = new HashMap<>();
        trama.put("request", requestBody);
        trama.put("response", responseBody);
        System.out.println("Envio:\n" + requestBody + "\nRespues:\n" + responseBody + "\nDuracion: " + duracion);
        
           ConexionLimbo cliente = new ConexionLimbo();
         cliente.processRequest(5, requestBody, responseBody, consumo, referencia);
        return trama;
    }
 
    public notificacionResponse.IFX registrarPagoIFX(String Rqid,String referencia,String valor) {
        disableSslVerification();
        
        
        
        notificacionResponse.IFX rsp = null;
        try { 
        notificacionRequest.IFX strIFX =new notificacionRequest.IFX(Rqid,referencia,valor);
        
        
        JAXBContext contextObj = JAXBContext.newInstance(notificacionRequest.IFX.class);
            
        StringWriter stringWriter = new StringWriter();
        Marshaller marshallerObj = contextObj.createMarshaller();
        marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            
        marshallerObj.marshal(strIFX, stringWriter);
            //  System.out.println(stringWriter.toString());
        String cadena = stringWriter.toString();
        
        Holder<String> holderxml = createParam(cadena); 
       
        athbugaifx.PSServiciosRecaudoService service = new athbugaifx.PSServiciosRecaudoService();
        athbugaifx.PSServiciosRecaudoBinding port = service.getPSServiciosRecaudoBinding();
        BindingProvider bindingProvider = (BindingProvider) port;
        List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
        handlerChain.add(new HandlerTrama());
        bindingProvider.getBinding().setHandlerChain(handlerChain);
        Map<String, Object> requestContext = bindingProvider.getRequestContext();
        requestContext.put("com.sun.xml.internal.ws.request.timeout", 3000);

        Instant durationStart = Instant.now();

        port.registrarPagoIFX(holderxml);
        
    
         rsp = new notificacionResponse.IFX(holderxml.value);
            
         Instant durationEnd = Instant.now();
         Duration duration = Duration.between(durationStart, durationEnd);

         Map<String, String> result = processRequest(bindingProvider, duration.toMillis(),referencia,"registrarPagoIFXATH");
        
         
        } catch (Exception e) {
             Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            if (e.getMessage().contains("timed out")) {
                System.out.println("timed out popayan Notificacion");
                Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            } else {
                System.out.println("Error ws popayan Notificacion");
                Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            }
        }
        return rsp;

    }

    public reversoResponse.IFX  reverso(String Rqid,String referencia,String valor) {
        disableSslVerification();
        
        
        reversoResponse.IFX rsp = null;
        try { 
        reversoRequest.IFX strIFX =new reversoRequest.IFX(Rqid,referencia,valor);
        
        
        JAXBContext contextObj = JAXBContext.newInstance(reversoRequest.IFX.class);
            
        StringWriter stringWriter = new StringWriter();
        Marshaller marshallerObj = contextObj.createMarshaller();
        marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            
        marshallerObj.marshal(strIFX, stringWriter);
        //  System.out.println(stringWriter.toString());
        String cadena = stringWriter.toString();
        
        Holder<String> holderxml = createParam(cadena); 
        
        athbugaifx.PSServiciosRecaudoService service = new athbugaifx.PSServiciosRecaudoService();
        athbugaifx.PSServiciosRecaudoBinding port = service.getPSServiciosRecaudoBinding();
        BindingProvider bindingProvider = (BindingProvider) port;
        List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
        handlerChain.add(new HandlerTrama());
        bindingProvider.getBinding().setHandlerChain(handlerChain);
        Map<String, Object> requestContext = bindingProvider.getRequestContext();
        requestContext.put("com.sun.xml.internal.ws.request.timeout", 3000);

        Instant durationStart = Instant.now();

        port.reverso(holderxml);
        
         rsp = new reversoResponse.IFX(holderxml.value);
            
         Instant durationEnd = Instant.now();
         Duration duration = Duration.between(durationStart, durationEnd);

         Map<String, String> result = processRequest(bindingProvider, duration.toMillis(),referencia,"reversoATH");
        } catch (Exception e) {
             Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            if (e.getMessage().contains("timed out")) {
                System.out.println("timed out popayan Reverso");
                Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            } else {
                System.out.println("Error ws popayan Reverso");
                Logger.getLogger(BugaAth.class.getName()).log(Level.SEVERE, null, e);
            }
        }
        return rsp;

    }
    
}
