package com.ferrologic.openb2b;

import java.lang.*;
import java.io.*;
import java.net.*;
import java.util.*;

import javax.activation.*;

import javax.xml.transform.*;
import javax.xml.soap.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;

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

import org.w3c.dom.xpath.XPathEvaluator;
import org.w3c.dom.xpath.XPathNSResolver;
import org.w3c.dom.xpath.XPathResult;
import org.xml.sax.InputSource;

import org.apache.xpath.domapi.XPathEvaluatorImpl;

public class DocumentHandler
{
    public void handleDocument(Document doc)
    {
	System.out.println("INFO: DocumentHandler.handleDocument: Processing document...");

	try {
	    translateDocument(doc);
	    
	    OpenB2BUtil.documentToStream(doc, System.out);

	    transformAndHttpSubmit(doc, 
				   OpenB2BConfig.getXsltPath() + "order.xslt",
				   new URL(OpenB2BConfig.getResponseURL()),
				   new HttpAuthenticator());

	    transformAndStore(doc, 
			      OpenB2BConfig.getXsltPath() + "orderflat.xslt",
			      OpenB2BConfig.getTextOutputPath(),
			      "flat",
			      "txt");

	    transformAndStore(doc, 
			      OpenB2BConfig.getXsltPath() + "orderhtml.xslt",
			      OpenB2BConfig.getHtmlOutputPath(),
			      "html",
			      "html");
	}
	catch(Exception e) {
	    System.out.println("EXCEPTION: DocumentHandler.handleDocument: " + e.getMessage());
	}
    }

    protected void transformAndHttpSubmit(Document doc, 
					  String xslt, 
					  URL url,
					  Authenticator auth) {
	try{
	    TransformerFactory transformerFactory = TransformerFactory.newInstance();

	    Transformer transformer = transformerFactory.newTransformer(new StreamSource(xslt));
	
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();
	
	    transformer.transform(new DOMSource(doc), 
				  new StreamResult(new OutputStreamWriter(baos)));

	    OpenB2BUtil.httpPostSubmit(auth, url, baos);
	}
	catch(Exception e) {
	    System.out.println("EXCEPTION: DocumentHandler.transformAndHttpSubmit: " + e.getMessage());
	}
    }

    protected void transformAndStore(Document doc, 
				     String xslt, 
				     String path, 
				     String type,
				     String ext) {
	try {
	    TransformerFactory transformerFactory = TransformerFactory.newInstance();
	    Transformer transformer = transformerFactory.newTransformer(new StreamSource(xslt));

	    // UGLY HACK ALERT! This works only for non XML output
	    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

	    FileOutputStream fos = OpenB2BUtil.createStampedFile(path, type, ext);

	    transformer.transform(new DOMSource(doc), 
				  new StreamResult(new OutputStreamWriter(fos)));

	    fos.close();
	}
	catch(Exception e) {
	    System.out.println("EXCEPTION: DocumentHandler.transformAndStore: " + e.getMessage());
	}
    }

    private String fetchTranslation(Document doc) {
	Node n;
	String result = "en_en";

	try{
	    // Create an XPath evaluator and pass in the document.
	    XPathEvaluator evaluator = new XPathEvaluatorImpl(doc);
	    XPathNSResolver resolver = evaluator.createNSResolver(doc);

	    String cust_lang_xpath = "/Order/OrderHeader/CustomerParty/PartyIdentification/PartyIdentifier/@languageCode";
	    String cust_lang_code = "fr";
	    XPathResult cust_lang = (XPathResult)evaluator.evaluate(cust_lang_xpath, 
								    doc, 
								    resolver, 
								    XPathResult.FIRST_ORDERED_NODE_TYPE, 
								    null);
	    n = cust_lang.getSingleNodeValue();

	    if(n != null)
		cust_lang_code = n.getNodeValue().toLowerCase();

	    String sell_lang_xpath = "/Order/OrderHeader/SellerParty/PartyIdentification/PartyIdentifier/@languageCode";
	    String sell_lang_code = "en";
	    XPathResult sell_lang = (XPathResult)evaluator.evaluate(sell_lang_xpath, 
								    doc, 
								    resolver, 
								    XPathResult.FIRST_ORDERED_NODE_TYPE, 
								    null);
	    n = sell_lang.getSingleNodeValue();
	
	    if(n != null)
		sell_lang_code = n.getNodeValue().toLowerCase();
	    
	    result = cust_lang_code + "_" + sell_lang_code;
	}
	catch(Exception e) {
	    System.out.println("EXCEPTION: DocumentHandler.fetchTranslation: " + e.getMessage());
	}

	return result;
    }
    
    private void translateDocument(Document doc) {
	Node n;

	try {
	    // Create an XPath evaluator and pass in the document.
	    XPathEvaluator evaluator = new XPathEvaluatorImpl(doc);
	    XPathNSResolver resolver = evaluator.createNSResolver(doc);

	    String ohn_xpath = "/Order/OrderHeader/OrderHeaderNote";
	    XPathResult ohn = (XPathResult)evaluator.evaluate(ohn_xpath, 
							      doc, 
							      resolver, 
							      XPathResult.UNORDERED_NODE_ITERATOR_TYPE, 
							      null);
	
	    while ((n = ohn.iterateNext()) != null) {
		if(n.getNodeType() == Node.ELEMENT_NODE) {
		    
		    Node text = n.getFirstChild();
		    String selection = fetchTranslation(doc);
		    String input = text.getNodeValue();
		    String tmp_result = OpenB2BUtil.translateString(selection, input);
		    String result = OpenB2BUtil.etitifyIsoString(tmp_result);

		    text.setNodeValue(result);
		}
	    }
	}
	catch(Exception e) {
	    System.out.println("EXCEPTION: DocumentHandler.translateDocument: " + e.getMessage());
	}
    }
}





