/*
 * 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 de.christofreichardt.jaxws.securitypriceservice;

import de.christofreichardt.diagnosis.AbstractTracer;
import de.christofreichardt.diagnosis.LogLevel;
import de.christofreichardt.diagnosis.Traceable;
import de.christofreichardt.diagnosis.TracerFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.soap.SOAPFaultException;

/**
 *
 * @author student
 */
public class App implements Traceable {
  
  private void call(SecurityPriceServiceRequest securityPriceServiceRequest) throws MalformedURLException, SecurityPriceServiceException, GeneralSecurityException, IOException {
    AbstractTracer tracer = getCurrentTracer();
    tracer.entry("void", this, "call()");
    
    try {
      URL url = new URL("http://127.0.1.1:8080/SecurityPriceService-server-0.0.1-SNAPSHOT/securitypriceservice?wsdl");
      QName qName = new QName("http://securitypriceservice.jaxws.christofreichardt.de/", "SecurityPriceService");
      SecurityPriceService securityPriceService = new SecurityPriceService(url, qName);
      SecurityPriceServicePortType securityPriceServicePort = securityPriceService.getPort(SecurityPriceServicePortType.class);
      
      Class<?>[] interfaces = securityPriceServicePort.getClass().getInterfaces();
      for (Class<?> interfaze : interfaces) {
        tracer.out().printfIndentln("interfaze.getName() = %s", interfaze.getName());
      }
      
      BindingProvider bindingProvider = (BindingProvider) securityPriceServicePort;
      bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:7070/SecurityPriceService-server-0.0.1-SNAPSHOT/securitypriceservice");
//      bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://127.0.1.1:8080/SecurityPriceService-server-0.0.1-SNAPSHOT/securitypriceservice");
      List<Handler> handlerChain = bindingProvider.getBinding().getHandlerChain();
      handlerChain.add(new SignatureHandler());
      bindingProvider.getBinding().setHandlerChain(handlerChain);
      
      SecurityPriceServiceResponse securityPriceServiceResponse = securityPriceServicePort.findPrice(securityPriceServiceRequest);
      tracer.out().printfIndentln("securityPriceServiceResponse.getTimestamp() = %s", securityPriceServiceResponse.getTimestamp());
      List<AbstractSecurityPrice> securityPrices = securityPriceServiceResponse.getSharePriceOrIndexPriceOrOptionPrice();
      for (AbstractSecurityPrice securityPrice : securityPrices) {
        tracer.out().printfIndentln("%s", securityPrice);
      }
    }
    finally {
      tracer.wayout();
    }
  }
  
  private SecurityPriceServiceRequest readRequest(File requestFile) throws JAXBException {
    AbstractTracer tracer = getCurrentTracer();
    tracer.entry("SecurityPriceServiceRequest", this, "readRequest(File requestFile)");
    
    try {
      StreamSource streamSource = new StreamSource(requestFile);
      JAXBContext jaxbContext = JAXBContext.newInstance(SecurityPriceServiceRequest.class);
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      JAXBElement<SecurityPriceServiceRequest> jaxbServiceRequest = unmarshaller.unmarshal(streamSource, SecurityPriceServiceRequest.class);
      
      return jaxbServiceRequest.getValue();
    }
    finally {
      tracer.wayout();
    }
  }

  @Override
  public AbstractTracer getCurrentTracer() {
    return TracerFactory.getInstance().getCurrentPoolTracer();
  }

  /**
   * @param args the command line arguments
   * @throws de.christofreichardt.diagnosis.TracerFactory.Exception
   * @throws javax.xml.bind.JAXBException
   */
  public static void main(String[] args) throws TracerFactory.Exception, JAXBException {
    TracerFactory.getInstance().reset();
    InputStream resourceAsStream = App.class.getClassLoader().getResourceAsStream("de/christofreichardt/jaxws/securitypriceservice/trace-config.xml");
    if (resourceAsStream != null) {
      TracerFactory.getInstance().readConfiguration(resourceAsStream);
    }
    TracerFactory.getInstance().openPoolTracer();
    
    try {
      AbstractTracer tracer = TracerFactory.getInstance().getCurrentPoolTracer();
      tracer.initCurrentTracingContext();
      tracer.entry("void", App.class, "main(String[] args)");
      try {
        for (int i=0; i<args.length; i++) {
          tracer.out().printfIndentln("arg[%d] = %s", i, args[i]);
        }
        
        List<String> propertyNames = new ArrayList<>(System.getProperties().stringPropertyNames());
        Collections.sort(propertyNames);
        for (String propertyName : propertyNames) {
          tracer.out().printfIndentln("%s = %s", propertyName, System.getProperties().getProperty(propertyName));
        }
        
        try {
          App app = new App();
          File requestFile;
          if (args.length == 0)
            requestFile = new File("." + File.separator + "xml" + File.separator + "request-1.xml");
          else
            requestFile = new File("." + File.separator + "xml" + File.separator + args[0] + ".xml");
          SecurityPriceServiceRequest serviceRequest = app.readRequest(requestFile);
          app.call(serviceRequest);
        }
        catch (IOException | SecurityPriceServiceException | GeneralSecurityException | SOAPFaultException ex) {
          tracer.logException(LogLevel.ERROR, ex, App.class, "main(String[] args)");
        }
      }
      finally {
        tracer.wayout();
      }
    }
    finally {
      TracerFactory.getInstance().closePoolTracer();
    }
  }
  
}
