/*******************************************************************************
 * Copyright (c) 2001, 2007 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsdl.tests.util;


import java.io.FileOutputStream;
import java.util.Iterator;

import javax.wsdl.OperationType;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.BindingFault;
import org.eclipse.wst.wsdl.BindingInput;
import org.eclipse.wst.wsdl.BindingOperation;
import org.eclipse.wst.wsdl.BindingOutput;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.ExtensibilityElement;
import org.eclipse.wst.wsdl.ExtensibleElement;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Import;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.MessageReference;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.Part;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.Service;
import org.eclipse.wst.wsdl.Types;
import org.eclipse.xsd.XSDSchema;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


/**
 * @author Kihup Boo
 */
public class WSDLConverter extends DefinitionVisitor
{
  private Document doc;

  private Element description;

  private Element currentTypes;

  private Element currentService;

  private Element currentEndpoint;

  private Element currentInterface;

  private Element currentOperation;

  private Element currentBinding;

  private Element currentBindingOperation;

  private Element currentBindingInput;

  private Element currentBindingOutput;

  private Element currentBindingFault;

  private String wsdlNamespacePrefix;

  private String xsdNamespacePrefix;

  // Added for JUnit
  public WSDLConverter(String name)
  {
    super(name);
  }

  /**
   * @param definition
   */
  public WSDLConverter(Definition definition)
  {
    super(definition);
    // TODO Auto-generated constructor stub
  }

  public void generate20(String filename) throws Exception
  {
    createDocument();
    visit();
    serialize(filename);
  }

  private void serialize(String filename) throws Exception
  {
    Source domSource = new DOMSource(doc);
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
    transformer.transform(domSource, new StreamResult(new FileOutputStream(filename)));
  }

  private void createDocument() throws ParserConfigurationException
  {
    doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
  }

  private Element createWSDLElement(String name)
  {
    Element element = doc.createElementNS("http://www.w3.org/2004/08/wsdl", name);
    if (wsdlNamespacePrefix != null)
      element.setPrefix(wsdlNamespacePrefix);

    return element;
  }

  private void processDocumentation(Element docElement, Element parent)
  {
    if (docElement == null)
      return;

    Element adoptedDocElement = (Element)doc.importNode(docElement, true);
    parent.appendChild(adoptedDocElement);
  }

  protected void visitDefinition(Definition def)
  {
    description = createWSDLElement("description");
    processDocumentation(def.getDocumentationElement(), description);

    // TBD - Determine later if we want to convert the document to use SOAP 1.2.
    // However adding these two namespaces may not be harmful.
    description.setAttribute("xmlns:soapenv", "http://www.w3.org/2003/05/soap-envelop");
    description.setAttribute("xmlns:wsoap", "http://www.w3.org/2004/08/soap12");

    String targetNamespace = def.getTargetNamespace();
    if (targetNamespace != null)
      description.setAttribute("targetNamespace", targetNamespace);

    Iterator iterator = def.getNamespaces().keySet().iterator();
    String prefix = null;
    String namespace = null;
    /*
     xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"*/
    while (iterator.hasNext())
    {
      prefix = (String)iterator.next();
      namespace = def.getNamespace(prefix);

      if ("http://schemas.xmlsoap.org/wsdl/".equals(namespace))
      {
        if (prefix.length() == 0) // meant to be default namespace
          description.setAttribute("xmlns", "http://www.w3.org/2004/08/wsdl");
        else
        {
          description.setAttribute("xmlns:" + prefix, "http://www.w3.org/2004/08/wsdl");
          wsdlNamespacePrefix = prefix;
          description.setPrefix(wsdlNamespacePrefix);
        }
        continue;
      }

      // SOAP 1.2
      if ("http://schemas.xmlsoap.org/wsdl/soap/".equals(namespace))
      {
        // SOAP 1.2
        description.setAttribute("xmlns:" + prefix, "http://www.w3.org/2003/05/soap-envelop");

        // WSDL 2.0 binding for SOAP 1.2
        description.setAttribute("xmlns:wsoap", "http://www.w3.org/2004/08/soap12");
        continue;
      }

      //if ("http://schemas.xmlsoap.org/soap/encoding/".equals(namespace))
      //  continue;

      if ("http://www.w3.org/2001/XMLSchema".equals(namespace))
        xsdNamespacePrefix = prefix; // We will use this in visitImport().

      if (prefix.length() == 0) // meant to be default namespace
        description.setAttribute("xmlns" + prefix, namespace);
      else
        description.setAttribute("xmlns:" + prefix, namespace);
    }

    doc.appendChild(description);
    super.visitDefinition(def);

  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitImport(org.eclipse.wst.wsdl.Import)
   */
  protected void visitImport(Import wsdlImport)
  {
    // Determine if we <import> a schema.
    if (importingSchema(wsdlImport))
    {
      currentTypes = createWSDLElement("types");
      description.appendChild(currentTypes);

      //  <xs:import namespace="http://foo.com" schemaLocation= "bar.xsd"/>
      Element schemaImport = doc.createElementNS("http://www.w3.org/2001/XMLSchema", "import");
      if (xsdNamespacePrefix == null) // need to add one
      {
        description.setAttribute("xmlns:xs", "http://www.w3.org/2001/XMLSchema");
        xsdNamespacePrefix = "xs";
        schemaImport.setPrefix(xsdNamespacePrefix);
      }
      else if (!"".equals(xsdNamespacePrefix)) // it is not default namespace
        schemaImport.setPrefix(xsdNamespacePrefix);

      schemaImport.setAttribute("namespace", wsdlImport.getNamespaceURI());
      schemaImport.setAttribute("schemaLocation", wsdlImport.getLocationURI());
      processDocumentation(wsdlImport.getDocumentationElement(), schemaImport);
      currentTypes.appendChild(schemaImport);
    }
    else
    {
      Element importElement = wsdlImport.getElement();
      Element adoptedImportElement = (Element)doc.importNode(importElement, true);
      processDocumentation(wsdlImport.getDocumentationElement(), adoptedImportElement);
      description.appendChild(adoptedImportElement);
    }
  }

  private boolean importingSchema(Import myImport)
  {
    if (myImport.getDefinition() != null) // it is WSDL import
      return false;
    else
      return true;
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitTypes(org.eclipse.wst.wsdl.Types)
   */
  protected void visitTypes(Types types)
  {
    // currentTypes may have been created in visitImport().
    if (currentTypes == null)
    {
      currentTypes = createWSDLElement("types");
      processDocumentation(types.getDocumentationElement(), currentTypes);
      description.appendChild(currentTypes);
    }

    Iterator iterator = types.getSchemas().iterator();
    XSDSchema schema = null;
    Element schemaElement = null;
    Element adoptedSchemaElement = null;
    while (iterator.hasNext())
    {
      schema = (XSDSchema)iterator.next();
      schema.updateElement();
      schemaElement = schema.getElement();
      adoptedSchemaElement = (Element)doc.importNode(schemaElement, true);
      currentTypes.appendChild(adoptedSchemaElement);
    }
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitPart(org.eclipse.wst.wsdl.Part)
   */
  protected void visitPart(Part part)
  {
    // TODO Auto-generated method stub
  }

  protected void visitPortType(PortType portType)
  {
    currentInterface = createWSDLElement("interface");
    processDocumentation(portType.getDocumentationElement(), currentInterface);

    Element portTypeElement = portType.getElement();
    if (portTypeElement.hasAttribute("name"))
      currentInterface.setAttribute("name", portTypeElement.getAttribute("name"));

    description.appendChild(currentInterface);
    super.visitPortType(portType);
  }

  protected void visitOperation(Operation operation)
  {
    currentOperation = createWSDLElement("operation");
    processDocumentation(operation.getDocumentationElement(), currentOperation);

    Element operationElement = operation.getElement();
    if (operationElement.hasAttribute("name"))
      currentOperation.setAttribute("name", operationElement.getAttribute("name"));

    OperationType opType = operation.getStyle();
    if (OperationType.REQUEST_RESPONSE == opType)
      currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/in-out");
    else if (OperationType.SOLICIT_RESPONSE == opType)
      currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/out-in");
    else if (OperationType.NOTIFICATION == opType)
      currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/out-only");
    else if (OperationType.ONE_WAY == opType)
      currentOperation.setAttribute("pattern", "http://www.w3.org/2004/03/wsdl/in-only");

    currentInterface.appendChild(currentOperation);
    super.visitOperation(operation);
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitInput(org.eclipse.wst.wsdl.Input)
   */
  protected void visitInput(Input input)
  {
    Element currentInput = createWSDLElement("input");
    processDocumentation(input.getDocumentationElement(), currentInput);

    Element inputElement = input.getElement();

    if (inputElement.hasAttribute("name"))
      currentInput.setAttribute("messageLabel", inputElement.getAttribute("name"));

    Element partElement = getPartElement(input);
    if (partElement.hasAttribute("element"))
      currentInput.setAttribute("element", partElement.getAttribute("element"));
    // TBD - what if the part uses "type"?

    currentOperation.appendChild(currentInput);
  }

  private Element getPartElement(MessageReference messageRef)
  {
    Iterator iterator = messageRef.getEMessage().getEParts().iterator();
    // TBD - for now, take the first part.
    Part part = (Part)iterator.next();
    Element partElement = part.getElement();
    return partElement;
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitOutput(org.eclipse.wst.wsdl.Output)
   */
  protected void visitOutput(Output output)
  {
    Element currentOutput = createWSDLElement("output");
    processDocumentation(output.getDocumentationElement(), currentOutput);

    Element outputElement = output.getElement();

    if (outputElement.hasAttribute("name"))
      currentOutput.setAttribute("messageLabel", outputElement.getAttribute("name"));

    Element partElement = getPartElement(output);
    if (partElement.hasAttribute("element"))
      currentOutput.setAttribute("element", partElement.getAttribute("element"));
    // TBD - what if the part uses "type"?

    currentOperation.appendChild(currentOutput);
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitFault(org.eclipse.wst.wsdl.Fault)
   */
  protected void visitFault(Fault fault)
  {
    // TODO Auto-generated method stub

  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitBinding(org.eclipse.wst.wsdl.Binding)
   */
  protected void visitBinding(Binding binding)
  {
    currentBinding = createWSDLElement("binding");
    processDocumentation(binding.getDocumentationElement(), currentBinding);

    Element bindingElement = binding.getElement();
    if (bindingElement.hasAttribute("name"))
      currentBinding.setAttribute("name", bindingElement.getAttribute("name"));
    if (bindingElement.hasAttribute("type"))
      currentBinding.setAttribute("interface", bindingElement.getAttribute("type"));

    // TBD - is the next line fixed for SOAP?
    currentBinding.setAttribute("type", "http://www.w3.org/2004/08/wsdl/soap12");
    currentBinding.setAttribute("wsoap:protocol", "http://www.w3.org/2003/05/soap/bindings/HTTP");
    currentBinding.setAttribute("wsoap:mepDefault", "http://www.w3.org.2003/05/soap/mep/request-response");

    description.appendChild(currentBinding);
    super.visitBinding(binding);
  }

  protected void visitBindingOperation(BindingOperation operation)
  {
    currentBindingOperation = createWSDLElement("operation");
    processDocumentation(operation.getDocumentationElement(), currentBindingOperation);

    String operationName = operation.getEOperation().getName();

    // Determine prefix
    String prefix = null;
    String targetNamespace = null;
    Definition def = operation.getEnclosingDefinition();
    if (def != null)
      targetNamespace = def.getTargetNamespace();
    if (targetNamespace != null)
      prefix = def.getPrefix(targetNamespace);

    if (prefix == null)
      prefix = "";
    else
      prefix += ":";

    currentBindingOperation.setAttribute("ref", prefix + operationName);

    currentBinding.appendChild(currentBindingOperation);
    super.visitBindingOperation(operation);
  }

  protected void visitBindingInput(BindingInput input)
  {
    currentBindingInput = createWSDLElement("input");
    processDocumentation(input.getDocumentationElement(), currentBindingInput);

    Element inputElement = input.getElement();
    String inputName = input.getName();
    if (inputName != null)
      inputElement.setAttribute("name", inputName);

    currentBindingOperation.appendChild(currentBindingInput);
    super.visitBindingInput(input);
  }

  protected void visitBindingOutput(BindingOutput output)
  {
    currentBindingOutput = createWSDLElement("output");
    processDocumentation(output.getDocumentationElement(), currentBindingOutput);

    Element outputElement = output.getElement();
    String outputName = output.getName();
    if (outputName != null)
      outputElement.setAttribute("name", outputName);

    currentBindingOperation.appendChild(currentBindingOutput);
    super.visitBindingOutput(output);
  }

  protected void visitBindingFault(BindingFault fault)
  {
    currentBindingFault = createWSDLElement("fault");
    processDocumentation(fault.getDocumentationElement(), currentBindingFault);

    Element faultElement = fault.getElement();
    String faultName = fault.getName();
    if (faultName != null)
      faultElement.setAttribute("name", faultName);

    currentBindingOperation.appendChild(currentBindingFault);
    super.visitBindingFault(fault);
  }

  protected void visitService(Service service)
  {
    currentService = createWSDLElement("service");
    processDocumentation(service.getDocumentationElement(), currentService);

    Element serviceElement = service.getElement();
    if (serviceElement.hasAttribute("name"))
      currentService.setAttribute("name", serviceElement.getAttribute("name"));

    description.appendChild(currentService);
    super.visitService(service);
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitPort(org.eclipse.wst.wsdl.Port)
   */
  protected void visitPort(Port port)
  {
    currentEndpoint = createWSDLElement("endpoint");
    processDocumentation(port.getDocumentationElement(), currentEndpoint);

    Element portElement = port.getElement();
    if (portElement.hasAttribute("name"))
      currentEndpoint.setAttribute("name", portElement.getAttribute("name"));
    if (portElement.hasAttribute("binding"))
      currentEndpoint.setAttribute("binding", portElement.getAttribute("binding"));

    // Add interface to current service
    Binding binding = port.getEBinding();
    if (binding != null) // binding could not be resolved
    {
      Element bindingElement = binding.getElement();
      if (bindingElement.hasAttribute("type"))
        currentService.setAttribute("interface", bindingElement.getAttribute("type"));
    }

    currentService.appendChild(currentEndpoint);
    super.visitPort(port);
  }

  /* (non-Javadoc)
   * @see org.eclipse.wst.wsdl.tests.util.DefinitionVisitor#visitExtensibilityElement(org.eclipse.wst.wsdl.ExtensibleElement, org.eclipse.wst.wsdl.ExtensibilityElement)
   */
  protected void visitExtensibilityElement(ExtensibleElement owner, ExtensibilityElement extensibilityElement)
  {
    // TBD - It is not just SOAP binding
    if (owner instanceof org.eclipse.wst.wsdl.internal.impl.PortImpl)
    {
      Element soapElement = extensibilityElement.getElement();
      if (soapElement.hasAttribute("location"))
        currentEndpoint.setAttribute("address", soapElement.getAttribute("location"));
    }
    else
    {
      Element domElement = extensibilityElement.getElement();
      Element adoptedDOMElement = (Element)doc.importNode(domElement, true);

      if (owner instanceof org.eclipse.wst.wsdl.internal.impl.DefinitionImpl)
        description.insertBefore(adoptedDOMElement, description.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.ServiceImpl)
        currentService.insertBefore(adoptedDOMElement, currentService.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.PortTypeImpl)
        currentInterface.insertBefore(adoptedDOMElement, currentInterface.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.OperationImpl)
        currentOperation.insertBefore(adoptedDOMElement, currentOperation.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingImpl)
        currentBinding.insertBefore(adoptedDOMElement, currentBinding.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingOperationImpl)
        currentBindingOperation.insertBefore(adoptedDOMElement, currentBindingOperation.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingInputImpl)
        currentBindingInput.insertBefore(adoptedDOMElement, currentBindingInput.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingOutputImpl)
        currentBindingOutput.insertBefore(adoptedDOMElement, currentBindingOutput.getFirstChild());
      else if (owner instanceof org.eclipse.wst.wsdl.internal.impl.BindingFaultImpl)
        currentBindingFault.insertBefore(adoptedDOMElement, currentBindingFault.getFirstChild());

    }

  }

  public static Test suite()
  {
    TestSuite suite = new TestSuite();

    suite.addTest(new WSDLConverter("Convert")
      {
        protected void runTest()
        {
          testConvert();
        }
      });
    return suite;
  }

  public void testConvert()
  {
    try
    {
      Definition def = DefinitionLoader.load("d:/eclipse301/eclipse/workspace/org.eclipse.wst.wsdl.tests/PTATimeDistribution.wsdl");
      WSDLConverter converter = new WSDLConverter(def);
      converter.generate20("d:/eclipse301/eclipse/workspace/org.eclipse.wst.wsdl.tests/PTATimeDistribution20.wsdl");
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

  public static void main(String[] args)
  {
    junit.textui.TestRunner.run(suite());
    /*
     try
     {
     Definition def = DefinitionLoader.load(args[0]);
     WSDLConverter converter = new WSDLConverter(def);
     converter.generate20("test20.wsdl");
     }
     catch (Exception e)
     {
     e.printStackTrace();
     }*/
  }
}
