/*******************************************************************************
 * Copyright (c) 2002, 2008 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
 * yyyymmdd bug      Email and other contact information
 * -------- -------- -----------------------------------------------------------
 * 20070305   117034 makandre@ca.ibm.com - Andrew Mak, Web Services Explorer should support SOAP Headers
 * 20070413   176493 makandre@ca.ibm.com - Andrew Mak, WSE: Make message/transport stack pluggable
 * 20071024   206556 gilberta@ca.ibm.com - Gilbert Andrews
 * 20080905   246265 mahutch@ca.ibm.com  - Mark Hutchinson
 * 20080911   247096 kathy@ca.ibm.com  - Kathy Chan
 *******************************************************************************/
package org.eclipse.wst.ws.internal.explorer.platform.wsdl.datamodel;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.wsdl.Binding;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;
import javax.wsdl.Input;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.extensions.ExtensibilityElement;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.xml.namespace.QName;
import org.eclipse.wst.ws.internal.explorer.platform.perspective.TransportProviderRegistry;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.constants.BindingTypes;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.constants.FragmentConstants;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.IXSDFragment;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.XSDToFragmentConfiguration;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.XSDToFragmentController;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.fragment.impl.SOAPHeaderWrapperFragment;
import org.eclipse.wst.ws.internal.explorer.platform.wsdl.xsd.WSDLPartsToXSDTypeMapper;
import org.eclipse.wst.ws.internal.explorer.transport.ISOAPTransportProvider;
import org.eclipse.wst.ws.internal.explorer.transport.MessageContext;
import org.eclipse.wst.wsdl.binding.soap.SOAPHeader;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDNamedComponent;

public class WSDLOperationElement extends WSDLCommonElement
{
  public static final int OPERATION_TYPE_SOAP = 0;
  public static final int OPERATION_TYPE_HTTP_GET = 1;
  public static final int OPERATION_TYPE_HTTP_POST = 2;

  private int operationType_;
  private Operation operation_;
  private WSDLPartsToXSDTypeMapper wsdlPartsToXsdTypeMapper_;
  private XSDToFragmentController fragController_;
  private boolean isDocumentStyle_;
  private boolean isUseLiteral_;
  private String soapAction_;
  private String encodingStyle_;
  private String encodingNamespace_;

  private Map headerCache;
  
  private MessageContext messageContext = null;
  private ISOAPTransportProvider soapTransportProvider = null;  
  
  private final void gatherSoapInformation(WSDLBindingElement bindingElement,SOAPBinding soapBinding)
  {
    // Initialize defaults.
    isDocumentStyle_ = true;
    soapAction_ = "";
    isUseLiteral_ = true;
    encodingStyle_ = null;
    encodingNamespace_ = null;

    if (soapBinding != null)
      isDocumentStyle_ = "document".equals(soapBinding.getStyle());
    BindingOperation bindingOperation = getBindingOperation(bindingElement);
    SOAPOperation soapOperation = null;
    
    for (Iterator i = bindingOperation.getExtensibilityElements().iterator();i.hasNext();)
    {
      ExtensibilityElement e = (ExtensibilityElement)i.next();
      if (e instanceof SOAPOperation)
      {
        soapOperation = (SOAPOperation)e;
        soapAction_ = soapOperation.getSoapActionURI();
        if(soapAction_ == null) soapAction_ = "";
        
        String style = soapOperation.getStyle();
        if (style != null)
          isDocumentStyle_ = style.equals("document");
        break;
      }
    }

    BindingInput bindingInput = bindingOperation.getBindingInput();
    SOAPBody soapBody = null;
    for (Iterator i = bindingInput.getExtensibilityElements().iterator();i.hasNext();)
    {
      ExtensibilityElement e = (ExtensibilityElement)i.next();
      if (e instanceof SOAPBody)
      {
        soapBody = (SOAPBody)e;
        isUseLiteral_ = "literal".equals(soapBody.getUse());
        if (!isUseLiteral_)
        {
          // Encoded.
          for (Iterator j = soapBody.getEncodingStyles().iterator();j.hasNext();)
          {
            encodingStyle_ = (String)j.next();
            encodingNamespace_ = soapBody.getNamespaceURI();
            break;
          }
        }
        break;
      }
    }
  }

  public WSDLOperationElement(String name,WSDLBindingElement bindingElement,Operation operation)
  {
    super(name, bindingElement.getModel());
    // Set the default operation type to be SOAP.
    setOperation(bindingElement,operation);
  }

  private Definition getDefinition(WSDLBindingElement bindingElement) {
	  WSDLServiceElement serviceElement = (WSDLServiceElement) bindingElement.getParentElement();
      WSDLElement wsdlElement = (WSDLElement) serviceElement.getParentElement();
      return wsdlElement.getDefinition();
  }
  
  private void setMessageContext(WSDLBindingElement bindingElement) {
	  messageContext = new MessageContext();
	  messageContext.setDefinition(getDefinition(bindingElement));
	  messageContext.setBindingOperation(getBindingOperation(bindingElement));
	  messageContext.setBindingProtocol(bindingElement.getBindingExtensibilityElement());
	  messageContext.setDocumentStyle(isDocumentStyle_);
  }
  
  public MessageContext getMessageContext() {
	  return messageContext;
  }
  
  private void setSOAPTransportProvider(SOAPBinding soapBinding) {
	  	  
	  String namespaceURI = soapBinding.getElementType().getNamespaceURI();
	  String transportURI = soapBinding.getTransportURI();
	  	  
	  soapTransportProvider = TransportProviderRegistry.getInstance()
	  	.getSOAPTransportProvider(namespaceURI, transportURI);
  }
  
  public ISOAPTransportProvider getSOAPTransportProvider() {
	  return soapTransportProvider;
  }
  
  public void setOperation(WSDLBindingElement bindingElement,Operation operation) {
    operation_ = operation;
    setDocumentation(operation.getDocumentationElement());
    fragController_ = null;
    wsdlPartsToXsdTypeMapper_ = null;
    operationType_ = bindingElement.getBindingType();
    ExtensibilityElement bindingExtensibilityElement = bindingElement.getBindingExtensibilityElement();
    switch (operationType_)
    {
      case BindingTypes.SOAP:
        gatherSoapInformation(bindingElement,(SOAPBinding)bindingExtensibilityElement);
        setMessageContext(bindingElement);
        setSOAPTransportProvider((SOAPBinding) bindingExtensibilityElement);
        headerCache = new Hashtable();
      case BindingTypes.HTTP_GET:
      case BindingTypes.HTTP_POST:
      default:
        break;
    }
  }

  public Operation getOperation() {
    return operation_;
  }

  public BindingOperation getBindingOperation()
  {
    return getBindingOperation((WSDLBindingElement)getParentElement());
  }

  private BindingOperation getBindingOperation(WSDLBindingElement bindingElement)
  {
    Binding binding = bindingElement.getBinding();
    String operationInputName = null;
    String operationOutputName = null;
    Input operationInput = operation_.getInput();
    Output operationOutput = operation_.getOutput();
    if (operationInput != null)
      operationInputName = operationInput.getName();
    if (operationOutput != null)
      operationOutputName = operationOutput.getName();
    BindingOperation bindingOperation = binding.getBindingOperation(operation_.getName(),operationInputName,operationOutputName);
    if (bindingOperation == null)
      bindingOperation = binding.getBindingOperation(operation_.getName(),null,null);
    return bindingOperation;
  }

  /**
   * Return a list of input headers.
   * 
   * @return A List
   */
  public List getSOAPHeaders() {
	  return getSOAPHeaders(true);
  }
	  
  /**
   * Return a list of headers.
   * 
   * @param isInput If true, returns the input headers.  If false, returns the output headers.
   * @return A List
   */
  public List getSOAPHeaders(boolean isInput) {
	  List headers = new Vector();
	
      BindingOperation bindingOperation = getBindingOperation();
	  List extensibilityElements = isInput ?
			bindingOperation.getBindingInput().getExtensibilityElements() : 
			bindingOperation.getBindingOutput().getExtensibilityElements();	  	  
	  
	  for (Iterator it = extensibilityElements.iterator(); it.hasNext();) {
	      
		  ExtensibilityElement e = (ExtensibilityElement) it.next();
	      
	      if (e instanceof SOAPHeader && !headers.contains(e))	    	 
    		  headers.add(e);
	  }   
	  
	  return headers;
  }  
  
  public List getOrderedBodyParts()
  {
    List parts = new Vector(operation_.getInput().getMessage().getOrderedParts(operation_.getParameterOrdering()));
    BindingOperation bindingOperation = getBindingOperation();
    BindingInput bindingInput = bindingOperation.getBindingInput();
    for (Iterator it = bindingInput.getExtensibilityElements().iterator(); it.hasNext();)
    {
      ExtensibilityElement e = (ExtensibilityElement)it.next();
      if (e instanceof SOAPBody)
      {
        SOAPBody soapBody = (SOAPBody)e;
        List bodyParts = soapBody.getParts();
        if (bodyParts != null)
        {
          for (int i = 0; i < parts.size(); i++)
          {
            Part part = (Part)parts.get(i);
            if (!bodyParts.contains(part) && !bodyParts.contains(part.getName()))
            {
              parts.remove(i);
              i--;
            }
          }
        }
        break;
      }
    }
    return parts;
  }

  private XSDToFragmentController getXSDToFragmentController() {
    if (fragController_ == null) {
      fragController_ = new XSDToFragmentController();
      fragController_.setWSDLPartsToXSDTypeMapper(wsdlPartsToXsdTypeMapper_);
    }
    return fragController_;
  }

  private XSDNamedComponent getSchema(Part part, String id) {
    if (wsdlPartsToXsdTypeMapper_ == null) {
      wsdlPartsToXsdTypeMapper_ = new WSDLPartsToXSDTypeMapper();
      WSDLBindingElement bindingElement = (WSDLBindingElement)getParentElement();
      WSDLServiceElement serviceElement = (WSDLServiceElement)bindingElement.getParentElement();
      WSDLElement wsdlElement = (WSDLElement)serviceElement.getParentElement();
      wsdlPartsToXsdTypeMapper_.addSchemas(wsdlElement.getSchemaList());
    }
    return wsdlPartsToXsdTypeMapper_.getXSDType(part, id);
  }

  public IXSDFragment getHeaderFragment(SOAPHeader soapHeader) {
	return getHeaderFragment(soapHeader, true);
  }
  
  public IXSDFragment getHeaderFragment(SOAPHeader soapHeader, boolean isInput) {
	StringBuffer id = new StringBuffer();
	Part part = soapHeader.getEPart();
	if (isInput)
	  id.append(FragmentConstants.INPUT_ID).append(soapHeader.getMessage()).append(FragmentConstants.PART_TOKEN);
	else
	  id.append(FragmentConstants.OUTPUT_ID).append(soapHeader.getMessage()).append(FragmentConstants.PART_TOKEN);
	
	return getFragment(part, id, true, isInput); // only wrap input header fragments
  }
  
  public IXSDFragment getFragment(Part part) {
    return getFragment(part, true);
  }

  public IXSDFragment getFragment(Part part, boolean isInput) {
    StringBuffer id = new StringBuffer();
    if (isInput)
      id.append(FragmentConstants.INPUT_ID);
    else
      id.append(FragmentConstants.OUTPUT_ID);

	return getFragment(part, id, false, false);
  }
  
  private IXSDFragment getFragment(Part part, StringBuffer id, boolean isHeader, boolean useSOAPHeaderWrapper) {
    String partName = part.getName();
    id.append(partName);
    XSDToFragmentConfiguration config = new XSDToFragmentConfiguration();
    config.setIsWSDLPart(true);
    config.setWSDLPartName(partName);
    config.setXSDComponent(getSchema(part, id.toString()));
    if (isDocumentStyle() || isHeader)
      config.setStyle(FragmentConstants.STYLE_DOCUMENT);
    else
      config.setStyle(FragmentConstants.STYLE_RPC);
    if (operationType_ == BindingTypes.SOAP)
    {
      if (!isUseLiteral_)
        config.setPartEncoding(FragmentConstants.ENCODING_SOAP);
    }
    else
      config.setPartEncoding(FragmentConstants.ENCODING_URL);

    //bug 246265: for usability, if the type is a soap encoded string then we do not want to display or send the optional "id" or "href" attributes
    QName typeName = part.getTypeName();
    if (typeName != null) {
    	String localPart = typeName.getLocalPart();
    	String namespaceURI = typeName.getNamespaceURI();

    	if ("string".equals(localPart) && "http://schemas.xmlsoap.org/soap/encoding/".equals(namespaceURI) ) {
    		if (config.getXSDComponent() instanceof XSDComplexTypeDefinition) {
    			XSDComplexTypeDefinition xsd = (XSDComplexTypeDefinition)config.getXSDComponent();
    			xsd.getAttributeUses().clear();
    			xsd.getAttributeContents().clear();
    		}
    	}
    }
  
    IXSDFragment fragment = getXSDToFragmentController().getFragment(config, id.toString(), part.getName());
     
    // let's see if there's a corresponding wrapper for this fragment
    if (useSOAPHeaderWrapper && !(fragment instanceof SOAPHeaderWrapperFragment)) {
    	SOAPHeaderWrapperFragment wrapper = (SOAPHeaderWrapperFragment) headerCache.get(fragment.getID());
    	
    	// no wrapper, let's wrap it
    	if (wrapper == null) {
    		wrapper = new SOAPHeaderWrapperFragment(fragment);    		
    		headerCache.put(fragment.getID(), wrapper);
    		
    		// also put this wrapper fragment in the master cache
    		getXSDToFragmentController().addToCache(wrapper.getID(), wrapper);
    	}
    	
    	return wrapper;
    }
    
    return fragment;
  }

  public IXSDFragment getFragmentByID(String id) {
    return getXSDToFragmentController().getCachedFragment(id);
  }

  public void removeAllFragment() {
    getXSDToFragmentController().emptyCache();
  }

  public boolean isDocumentStyle()
  {
    return isDocumentStyle_;
  }

  public String getSoapAction()
  {
    return soapAction_;
  }

  public boolean isUseLiteral()
  {
    return isUseLiteral_;
  }

  public String getEncodingStyle()
  {
    return encodingStyle_;
  }

  public String getEncodingNamespace()
  {
    return encodingNamespace_;
  }

  public int getOperationType()
  {
    return operationType_;
  }
}
