/*******************************************************************************
 * 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;


import java.util.Iterator;

import javax.xml.namespace.QName;

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

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
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.Message;
import org.eclipse.wst.wsdl.MessageReference;
import org.eclipse.wst.wsdl.Namespace;
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.wst.wsdl.UnknownExtensibilityElement;
import org.eclipse.wst.wsdl.WSDLElement;
import org.eclipse.wst.wsdl.WSDLFactory;
import org.eclipse.wst.wsdl.WSDLPlugin;
import org.eclipse.wst.wsdl.XSDSchemaExtensibilityElement;
import org.eclipse.wst.wsdl.binding.soap.SOAPAddress;
import org.eclipse.wst.wsdl.binding.soap.SOAPBinding;
import org.eclipse.wst.wsdl.binding.soap.SOAPBody;
import org.eclipse.wst.wsdl.binding.soap.SOAPFactory;
import org.eclipse.wst.wsdl.binding.soap.SOAPFault;
import org.eclipse.wst.wsdl.binding.soap.SOAPHeader;
import org.eclipse.wst.wsdl.binding.soap.SOAPHeaderBase;
import org.eclipse.wst.wsdl.binding.soap.SOAPHeaderFault;
import org.eclipse.wst.wsdl.binding.soap.SOAPOperation;
import org.eclipse.wst.wsdl.internal.util.WSDLResourceFactoryImpl;
import org.eclipse.wst.wsdl.tests.util.DefinitionLoader;
import org.eclipse.wst.wsdl.tests.util.DefinitionVisitor;
import org.eclipse.wst.wsdl.util.WSDLResourceImpl;


/**
 * @author Kihup Boo
 */
public class WSDLEMFAPITest extends DefinitionVisitor
{
  private String PLUGIN_ABSOLUTE_PATH = WSDLTestsPlugin.getInstallURL();

  private WSDLFactory factory = WSDLFactory.eINSTANCE;

  Definition newDefinition;

  private Message currentMessage;

  private Service currentService;

  private PortType currentPortType;

  private Operation currentOperation;

  private Binding currentBinding;

  private BindingOperation currentBindingOperation;

  private ExtensibleElement currentExtensibleElement;

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

  /**
   * @param definition
   */
  public WSDLEMFAPITest(Definition definition)
  {
    super(definition);
  }

  protected void visitDefinition(Definition def)
  {
    // Use WSDLElement to increase the API coverage in the reports
    WSDLElement root = factory.createDefinition();
    newDefinition = (Definition)root;

    root.setDocumentationElement(def.getDocumentationElement());
    root.getDocumentationElement();
    root.setEnclosingDefinition(newDefinition);
    root.getEnclosingDefinition();
    root.getContainer();

    newDefinition.setQName(def.getQName());
    newDefinition.setTargetNamespace(def.getTargetNamespace());
    newDefinition.setDocumentBaseURI(def.getDocumentBaseURI());
    newDefinition.setLocation(def.getLocation());
    newDefinition.setEncoding(def.getEncoding());

    // getENamespaces does not work.
    Iterator iterator = def.getENamespaces().iterator();
    Namespace ns = null;
    String prefix = null;
    String uri = null;
    while (iterator.hasNext())
    {
      ns = factory.createNamespace();
      prefix = ((Namespace)iterator.next()).getPrefix();
      uri = ((Namespace)iterator.next()).getURI();
      ns.setURI(uri);
      ns.setPrefix(prefix);
      newDefinition.getENamespaces().add(ns);
    }

    iterator = def.getNamespaces().keySet().iterator();
    prefix = null;
    String namespace = null;

    while (iterator.hasNext())
    {
      prefix = (String)iterator.next();
      namespace = def.getNamespace(prefix);
      newDefinition.addNamespace(prefix, namespace);
    }
    //newDefinition.updateElement();

    currentExtensibleElement = def;
    super.visitDefinition(def);

    root.setElement(null);
    root.updateElement(true);
    root.getElement();
    root.setElement(null);
    root.updateElement();
  }

  protected void visitImport(Import wsdlImport)
  {
    Import myImport = factory.createImport();
    newDefinition.getEImports().add(myImport);

    // e.g. <xs:import namespace="http://foo.com" schemaLocation= "bar.xsd"/>
    myImport.setNamespaceURI(wsdlImport.getNamespaceURI());
    myImport.setLocationURI(wsdlImport.getLocationURI());
    myImport.setDocumentationElement(wsdlImport.getDocumentationElement());
    myImport.setEDefinition(wsdlImport.getEDefinition());
    myImport.setESchema(wsdlImport.getESchema());
    myImport.setSchema(wsdlImport.getSchema());
    myImport.setEnclosingDefinition(newDefinition);
  }

  protected void visitTypes(Types types)
  {
    Types myTypes = factory.createTypes();
    myTypes.setDocumentationElement(types.getDocumentationElement());

    Iterator iterator = types.getEExtensibilityElements().iterator();
    ExtensibilityElement ee = null;
    types.getSchemas("http://tempuri.org/LoadAndPrintTest/");

    currentExtensibleElement = myTypes;
    while (iterator.hasNext())
    {
      ee = (ExtensibilityElement)iterator.next();
      visitExtensibilityElement(ee);
    }

    myTypes.setEnclosingDefinition(newDefinition);
    newDefinition.getETypes();
    newDefinition.setETypes(myTypes);
  }

  protected void visitPart(Part part)
  {
    Part myPart = factory.createPart();
    myPart.setDocumentationElement(part.getDocumentationElement());
    myPart.setName(part.getName());
    myPart.setElementName(part.getElementName());
    myPart.setTypeName(part.getTypeName());
    myPart.setEMessage(part.getEMessage());
    myPart.setElementDeclaration(part.getElementDeclaration());
    myPart.setTypeDefinition(part.getTypeDefinition());

    Iterator iterator = part.getExtensionAttributes().keySet().iterator();
    QName key = null;
    QName value = null;
    while (iterator.hasNext())
    {
      key = (QName)iterator.next();
      value = (QName)part.getExtensionAttribute(key);
      myPart.setExtensionAttribute(key, value);
    }
    currentMessage.setEnclosingDefinition(newDefinition);
    currentMessage.addPart(myPart);
  }

  protected void visitPortType(PortType portType)
  {
    currentPortType = factory.createPortType();
    currentPortType.setDocumentationElement(portType.getDocumentationElement());
    currentPortType.setQName(portType.getQName());
    currentPortType.setUndefined(portType.isUndefined());

    currentPortType.setEnclosingDefinition(newDefinition);
    newDefinition.getEPortTypes().add(currentPortType);

    super.visitPortType(portType);
  }

  protected void visitOperation(Operation operation)
  {
    currentOperation = factory.createOperation();
    currentOperation.setDocumentationElement(operation.getDocumentationElement());
    currentOperation.setName(operation.getName());
    currentOperation.setStyle(operation.getStyle());
    currentOperation.setUndefined(operation.isUndefined());
    operation.getEParameterOrdering(); // TBD
    currentOperation.setEnclosingDefinition(newDefinition);
    currentPortType.getEOperations().add(currentOperation);

    super.visitOperation(operation);
    //System.out.println("Operation Type is: " + operation.getStyle());
    //operation.setStyle(OperationType.REQUEST_RESPONSE);
    //System.out.println("Operation Type is: " + operation.getStyle());
  }

  protected void visitMessage(Message message)
  {
    currentMessage = factory.createMessage();
    currentMessage.setQName(message.getQName());
    currentMessage.setUndefined(message.isUndefined());
    newDefinition.addMessage(currentMessage);

    super.visitMessage(message);
  }

  protected void visitInput(Input input)
  {
    MessageReference myInput = factory.createInput();
    myInput.setDocumentationElement(input.getDocumentationElement());
    myInput.setName(input.getName());
    myInput.getName();
    myInput.setEMessage(input.getEMessage());
    myInput.setEnclosingDefinition(newDefinition);
    currentOperation.setEInput((Input)myInput);
  }

  protected void visitOutput(Output output)
  {
    Output myOutput = factory.createOutput();
    myOutput.setDocumentationElement(output.getDocumentationElement());
    myOutput.setName(output.getName());
    myOutput.setEMessage(output.getEMessage());
    myOutput.setEnclosingDefinition(newDefinition);
    currentOperation.setEOutput(myOutput);
  }

  protected void visitFault(Fault fault)
  {
    Fault myFault = factory.createFault();
    myFault.setDocumentationElement(fault.getDocumentationElement());
    myFault.setName(fault.getName());
    myFault.setEMessage(fault.getEMessage());
    myFault.setEnclosingDefinition(newDefinition);
    currentOperation.getEFaults().add(myFault);
  }

  protected void visitBinding(Binding binding)
  {
    currentBinding = factory.createBinding();
    newDefinition.getEBindings().add(currentBinding);

    currentBinding.setDocumentationElement(binding.getDocumentationElement());
    currentBinding.setQName(binding.getQName());
    currentBinding.setEPortType(binding.getEPortType());
    currentBinding.setUndefined(binding.isUndefined());

    currentExtensibleElement = currentBinding;
    super.visitBinding(binding);
  }

  protected void visitBindingOperation(BindingOperation bindingOperation)
  {
    currentBindingOperation = factory.createBindingOperation();
    currentBindingOperation.setDocumentationElement(bindingOperation.getDocumentationElement());
    currentBindingOperation.setEOperation(bindingOperation.getEOperation());
    currentBindingOperation.setName(bindingOperation.getName());
    currentBinding.getBindingOperations().add(currentBindingOperation);

    currentExtensibleElement = currentBindingOperation;
    super.visitBindingOperation(bindingOperation);
  }

  protected void visitBindingInput(BindingInput input)
  {
    BindingInput myInput = factory.createBindingInput();
    myInput.setDocumentationElement(input.getDocumentationElement());
    myInput.setName(input.getName());
    myInput.setInput(input.getInput());
    myInput.setEInput(input.getEInput());
    currentBindingOperation.setEBindingInput(myInput);

    currentExtensibleElement = myInput;
    super.visitBindingInput(input);
  }

  protected void visitBindingOutput(BindingOutput output)
  {
    BindingOutput myOutput = factory.createBindingOutput();
    myOutput.setDocumentationElement(output.getDocumentationElement());
    myOutput.setName(output.getName());
    myOutput.setOutput(output.getOutput());
    myOutput.setEOutput(output.getEOutput());
    currentBindingOperation.setEBindingOutput(myOutput);

    currentExtensibleElement = myOutput;
    super.visitBindingOutput(output);
  }

  protected void visitBindingFault(BindingFault fault)
  {
    BindingFault myFault = factory.createBindingFault();
    myFault.setDocumentationElement(fault.getDocumentationElement());
    myFault.setName(fault.getName());
    myFault.setEFault(fault.getEFault());
    myFault.setFault(fault.getFault());
    currentBindingOperation.getEBindingFaults().add(myFault);

    currentExtensibleElement = myFault;
    super.visitBindingFault(fault);
  }

  protected void visitService(Service service)
  {
    currentService = factory.createService();
    currentService.setDocumentationElement(service.getDocumentationElement());
    currentService.setQName(service.getQName());
    currentService.setUndefined(service.isUndefined());

    newDefinition.getEServices().add(currentService);

    super.visitService(service);
  }

  protected void visitPort(Port port)
  {
    Port myPort = factory.createPort();
    myPort.setDocumentationElement(port.getDocumentationElement());
    myPort.setName(port.getName());
    myPort.setEBinding(port.getEBinding());

    currentService.getEPorts().add(myPort);

    currentExtensibleElement = myPort;
    super.visitPort(port);
  }

  protected void visitExtensibilityElement(ExtensibleElement owner, ExtensibilityElement extensibilityElement)
  {
    // To move up the API test coverage
    owner.getEExtensibilityElements();
    owner.getExtensibilityElements();
    factory.createExtensibilityElement();
    WSDLPlugin.getPlugin();
    WSDLPlugin.INSTANCE.getPluginResourceLocator();

    visitExtensibilityElement(extensibilityElement);
  }

  private void visitExtensibilityElement(ExtensibilityElement extensibilityElement)
  {
    XSDSchemaExtensibilityElement xsee = null;
    UnknownExtensibilityElement uee = null;
    ExtensibilityElement myEE = null;
    if (extensibilityElement instanceof XSDSchemaExtensibilityElement)
    {
      myEE = factory.createXSDSchemaExtensibilityElement();
      xsee = (XSDSchemaExtensibilityElement)myEE;
      xsee.setSchema(((XSDSchemaExtensibilityElement)extensibilityElement).getSchema());
    }
    else
    {
      myEE = factory.createUnknownExtensibilityElement();
      uee = (UnknownExtensibilityElement)myEE;
      uee.getChildren(); // TBD
    }
    myEE.setElementType(extensibilityElement.getElementType());
    myEE.setRequired(extensibilityElement.getRequired());
    myEE.setRequired(extensibilityElement.isRequired());
    if (currentExtensibleElement != null)
      currentExtensibleElement.addExtensibilityElement(myEE);

    if (extensibilityElement instanceof SOAPBody)
      visitSOAPBody((SOAPBody)extensibilityElement);
    else if (extensibilityElement instanceof SOAPBinding)
      visitSOAPBinding((SOAPBinding)extensibilityElement);
    else if (extensibilityElement instanceof SOAPAddress)
      visitSOAPAddress((SOAPAddress)extensibilityElement);
    else if (extensibilityElement instanceof SOAPOperation)
      visitSOAPOperation((SOAPOperation)extensibilityElement);
    else if (extensibilityElement instanceof SOAPFault)
      visitSOAPFault((SOAPFault)extensibilityElement);
    else if (extensibilityElement instanceof SOAPHeader)
      visitSOAPHeader((SOAPHeader)extensibilityElement);
    else if (extensibilityElement instanceof SOAPHeaderFault)
      visitSOAPHeaderFault((SOAPHeaderFault)extensibilityElement);
  }

  private void visitSOAPFault(SOAPFault soapFault)
  {
    SOAPFault mySoapFault = SOAPFactory.eINSTANCE.createSOAPFault();
    mySoapFault.setEncodingStyles(soapFault.getEncodingStyles());
    mySoapFault.setName(soapFault.getName());
    mySoapFault.setNamespaceURI(soapFault.getNamespaceURI());
    mySoapFault.setUse(soapFault.getUse());
  }

  private void visitSOAPHeader(SOAPHeader soapHeader)
  {
    // Use SOAPHeaderBase to increase the API coverage values in the reports

    SOAPHeaderBase yourSoapHeader = SOAPFactory.eINSTANCE.createSOAPHeaderBase();
    yourSoapHeader.getEncodingStyles();

    SOAPHeaderBase mySoapHeader = SOAPFactory.eINSTANCE.createSOAPHeader();
    mySoapHeader.setMessage(soapHeader.getMessage());
    mySoapHeader.getMessage();
    mySoapHeader.setPart(soapHeader.getPart());
    mySoapHeader.getPart();
    mySoapHeader.setNamespaceURI(soapHeader.getNamespaceURI());
    mySoapHeader.getNamespaceURI();
    mySoapHeader.setUse(soapHeader.getUse());
    mySoapHeader.getUse();
    ((SOAPHeader)soapHeader).getHeaderFaults(); // TBD
  }

  private void visitSOAPHeaderFault(SOAPHeaderFault soapHeaderFault)
  {
    SOAPHeaderFault mySoapHeaderFault = SOAPFactory.eINSTANCE.createSOAPHeaderFault();
    mySoapHeaderFault.setMessage(soapHeaderFault.getMessage());
    mySoapHeaderFault.setPart(soapHeaderFault.getPart());
    mySoapHeaderFault.setNamespaceURI(soapHeaderFault.getNamespaceURI());
    mySoapHeaderFault.setUse(soapHeaderFault.getUse());
  }

  private void visitSOAPOperation(SOAPOperation soapOperation)
  {
    SOAPOperation mySoapOperation = SOAPFactory.eINSTANCE.createSOAPOperation();
    mySoapOperation.setSoapActionURI(soapOperation.getSoapActionURI());
    mySoapOperation.setStyle(soapOperation.getStyle());
  }

  private void visitSOAPBody(SOAPBody soapBody)
  {
    SOAPBody mySoapBody = SOAPFactory.eINSTANCE.createSOAPBody();
    mySoapBody.setEncodingStyles(soapBody.getEncodingStyles());
    mySoapBody.setNamespaceURI(soapBody.getNamespaceURI());
    mySoapBody.setParts(soapBody.getParts());
    mySoapBody.setUse(soapBody.getUse());
  }

  private void visitSOAPBinding(SOAPBinding soapBinding)
  {
    SOAPBinding mySoapBinding = SOAPFactory.eINSTANCE.createSOAPBinding();
    mySoapBinding.setStyle(soapBinding.getStyle());
    mySoapBinding.setTransportURI(soapBinding.getTransportURI());
  }

  private void visitSOAPAddress(SOAPAddress soapAddress)
  {
    SOAPAddress mySoapAddress = SOAPFactory.eINSTANCE.createSOAPAddress();
    mySoapAddress.setLocationURI(soapAddress.getLocationURI());
  }

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

    suite.addTest(new WSDLEMFAPITest("ModelSemanticTest")
      {
        protected void runTest()
        {
          testModelSemantic();
        }
      });
    return suite;
  }

  public void testModelSemantic()
  {
    try
    {
      Definition def = DefinitionLoader.load(PLUGIN_ABSOLUTE_PATH + "samples/LoadStoreCompare/LoadAndPrintTest.wsdl", true);
      WSDLEMFAPITest test = new WSDLEMFAPITest(def);
      test.visit();
      serialize(test.newDefinition);
    }
    catch (Exception e)
    {
      e.printStackTrace();
      Assert.fail(e.toString());
    }
  }

  private void serialize(Definition def) throws Exception
  {
    ResourceSet resourceSet = new ResourceSetImpl();
    resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("wsdl", new WSDLResourceFactoryImpl());
    WSDLResourceImpl wsdlMainResource = (WSDLResourceImpl)resourceSet.createResource(URI.createURI("*.wsdl"));
    wsdlMainResource.getContents().add(def);

    IWorkspaceRoot myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
    IProject myWebProject = myWorkspaceRoot.getProject("org.eclipse.wst.wsdl.tests");
    if (!myWebProject.exists())
      myWebProject.create(null);

    String baseDir = myWebProject.getLocation().toString();

    DefinitionLoader.store(def, baseDir + "/ClonedLoadAndPrintTest.wsdl");
  }

  public static void main(String[] args)
  {
    junit.textui.TestRunner.run(suite());
  }
}
