package org.ow2.orchestra.cxf.example.loanApprovalCamel;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Iterator;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.ow2.orchestra.facade.exception.OrchestraRuntimeException;
import org.ow2.orchestra.util.XmlUtil;

/**
 * Implementation of the RiskAssessment Web Service.
 *
 * Used in a route with a direct endpoint. The complete SOAP message is
 * in the In message of the Camel exchange.
 *
 * The process method is called by Camel.
 * This method parses the SOAP message to extract the parameters,
 * and then creates the reply SOAP message sent back to Orchestra.
 *
 * @author Guillaume Porcher
 *
 */
public class RiskAssessmentBindingImpl implements Processor {

  public java.lang.String check(final java.lang.String firstName,
      final java.lang.String name, final long amount)
    throws java.rmi.RemoteException {
    if ("Dupont".equals(name) || "McDonalds".equals(name)) {
      return "medium";
    } else if ("Kent".equals(name) || "Martin".equals(name)) {
      return "high";
    }
    return "low";
  }


  public void process(final Exchange exchange) throws Exception {
    // Parse input message
    final MessageFactory messageFactory = MessageFactory.newInstance();
    final SOAPMessage inMessage = messageFactory.createMessage(null, exchange.getIn().getMandatoryBody(InputStream.class));
    final Iterator<Node> it = inMessage.getSOAPBody().getChildElements();
    SOAPBodyElement result = null;
    while (it.hasNext()) {
      final Node item = it.next();
      if (item instanceof SOAPBodyElement) {
        if (result != null) {
          throw new OrchestraRuntimeException("response.soapBody.children has more than one child");
        }
        result = (SOAPBodyElement) item;
      }
    }
    if (result == null) {
      throw new OrchestraRuntimeException("response.soapBody.children has no child");
    }
    final String firstName = XmlUtil.element(result, "firstName").getTextContent();
    final String name = XmlUtil.element(result, "name").getTextContent();
    final long amount = Long.parseLong(XmlUtil.element(result, "amount").getTextContent());

    // Call method
    final String level = this.check(firstName, name, amount);

    // prepare output message
    final SOAPMessage soapMessage = messageFactory.createMessage();
    final SOAPPart soapPart = soapMessage.getSOAPPart();

    final SOAPEnvelope enveloppe = soapPart.getEnvelope();
    enveloppe.addNamespaceDeclaration("env", "http://schemas.xmlsoap.org/soap/envelope/");

    final SOAPBody soapBody = enveloppe.getBody();
    final SOAPElement levelElement = soapBody.addChildElement("result").addChildElement("level");
    levelElement.setTextContent(level);

    final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    soapMessage.writeTo(byteArrayOutputStream);
    byteArrayOutputStream.close();
    exchange.getOut().setBody(byteArrayOutputStream.toByteArray());
  }
}
