package org.eclipse.wst.wsdl.binding.soap.internal.generator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.common.util.BasicEList;
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.ExtensibilityElement;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Operation;
import org.eclipse.wst.wsdl.Output;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.PortType;
import org.eclipse.wst.wsdl.WSDLElement;
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.SOAPOperation;
import org.eclipse.wst.wsdl.internal.generator.ContentGenerator;

public class SOAPContentGenerator implements ContentGenerator
{	
	public static final int OPTION_NOT_SET = -1;
	
	public static final int STYLE_DOCUMENT = 1;
	public static final int STYLE_RPC = 2;
	
	public static final int USE_LITERAL = 1;
	public static final int USE_ENCODED = 2;
	
	private int styleOption = OPTION_NOT_SET;
	private int useOption = OPTION_NOT_SET;

  protected String namespaceValue = "";
  protected String addressLocation = ContentGenerator.ADDRESS_LOCATION;

  protected final static String[] requiredNamespaces = {"http://schemas.xmlsoap.org/wsdl/soap/"};
  protected final static String[] preferredNamespacePrefixes = {"soap"};
  
     
  public String[] getRequiredNamespaces()
  {
    return requiredNamespaces;
  }
  
  public String getPreferredNamespacePrefix(String namespace)
  {
	  if (namespace.equals("http://schemas.xmlsoap.org/wsdl/soap/")) {
		  return "soap";
	  }
	  
	  return "";
  }
  
  public void setStyle(int style) {
	  styleOption = style;
  }
  
  public void setUse(int use) {
	  useOption = use;
  }
  
  public void setAddressLocation(String addressLocation) {
	  this.addressLocation = addressLocation;
  }

  public void generatePortContent(Port port)
  {
	  // We blow away any existing ExtensibilityElements/content before we generate it
	  // Is it worth being smarter?  Look for matching content first and create those which aren't found????
	  List removeList = new ArrayList(port.getEExtensibilityElements());	  
	  removeExtensebilityElements(port.getEExtensibilityElements(), removeList);

	  SOAPAddress soapAddress= SOAPFactory.eINSTANCE.createSOAPAddress();
	  soapAddress.setLocationURI(addressLocation);
	  port.addExtensibilityElement(soapAddress);
  }  

  public void generateBindingContent(Binding binding, PortType portType)
  {	  
	  // We blow away any existing ExtensibilityElements/content before we generate it
	  // Is it worth being smarter?  Look for matching content first and create those which aren't found????
	  List removeList = new ArrayList(binding.getEExtensibilityElements());	  
	  removeExtensebilityElements(binding.getEExtensibilityElements(), removeList);
	
	SOAPFactory soapFactory = SOAPFactory.eINSTANCE;
	SOAPBinding soapBinding = soapFactory.createSOAPBinding();
	soapBinding.setStyle((getStyleOption(binding) == STYLE_DOCUMENT) ? "document" : "rpc");
	soapBinding.setTransportURI("http://schemas.xmlsoap.org/soap/http");
	
	binding.addExtensibilityElement(soapBinding);	
  }

  public void generateBindingOperationContent(BindingOperation bindingOperation, Operation operation)
  {
	  // We blow away any existing ExtensibilityElements/content before we generate it
	  // Is it worth being smarter?  Look for matching content first and create those which aren't found????
	  List removeList = new ArrayList(bindingOperation.getEExtensibilityElements());
	removeExtensebilityElements(bindingOperation.getEExtensibilityElements(), removeList);
	
	SOAPOperation soapOperation = SOAPFactory.eINSTANCE.createSOAPOperation();	
	
    String soapActionValue = getNamespace(bindingOperation);
    if (!soapActionValue.endsWith("/"))
    {                
      soapActionValue += "/";
    }                        
    soapActionValue += operation.getName();
	
	soapOperation.setSoapActionURI(soapActionValue);
	
	bindingOperation.addExtensibilityElement(soapOperation);	
  }  

  public void generateBindingInputContent(BindingInput bindingInput, Input input)
  {
	  // We blow away any existing ExtensibilityElements/content before we generate it
	  // Is it worth being smarter?  Look for matching content first and create those which aren't found????
	  List removeList = new ArrayList(bindingInput.getEExtensibilityElements());
	removeExtensebilityElements(bindingInput.getEExtensibilityElements(), removeList);
	
	SOAPFactory soapFactory = SOAPFactory.eINSTANCE;
	SOAPBody soapBody = soapFactory.createSOAPBody();
	soapBody.setUse((getUseOption(null) == USE_ENCODED) ? "encoded" : "literal");
	if (getUseOption(bindingInput) == USE_ENCODED && getStyleOption(bindingInput) == STYLE_RPC)
    {
		List encodingList = new BasicEList();
		encodingList.add("http://schemas.xmlsoap.org/soap/encoding/");
		soapBody.setEncodingStyles(encodingList);
	  	soapBody.setNamespaceURI(getNamespace(bindingInput));
    }
    else if (getUseOption(bindingInput) == USE_LITERAL && getStyleOption(bindingInput) == STYLE_RPC) {
	  	soapBody.setNamespaceURI(getNamespace(bindingInput));
    }
	
	bindingInput.addExtensibilityElement(soapBody);
  }

  public void generateBindingOutputContent(BindingOutput bindingOutput, Output output)
  {
	  // We blow away any existing ExtensibilityElements/content before we generate it
	  // Is it worth being smarter?  Look for matching content first and create those which aren't found????
	  List removeList = new ArrayList(bindingOutput.getEExtensibilityElements());
	removeExtensebilityElements(bindingOutput.getEExtensibilityElements(), removeList);
	
	SOAPFactory soapFactory = SOAPFactory.eINSTANCE;
	SOAPBody soapBody = soapFactory.createSOAPBody();
	soapBody.setUse((getUseOption(bindingOutput) == USE_ENCODED) ? "encoded" : "literal");
	if (getUseOption(bindingOutput) == USE_ENCODED && getStyleOption(bindingOutput) == STYLE_RPC)
    {
		List encodingList = new BasicEList();
		encodingList.add("http://schemas.xmlsoap.org/soap/encoding/");
		soapBody.setEncodingStyles(encodingList);
	  	soapBody.setNamespaceURI(getNamespace(bindingOutput));
    }
    else if (getUseOption(bindingOutput) == USE_LITERAL && getStyleOption(bindingOutput) == STYLE_RPC) {
	  	soapBody.setNamespaceURI(getNamespace(bindingOutput));
    }
	
	bindingOutput.addExtensibilityElement(soapBody);	
  }         

  public void generateBindingFaultContent(BindingFault bindingFault, Fault fault)
  {                            
	  // We blow away any existing ExtensibilityElements/content before we generate it
	  // Is it worth being smarter?  Look for matching content first and create those which aren't found????
	  List removeList = new ArrayList(bindingFault.getEExtensibilityElements());
	removeExtensebilityElements(bindingFault.getEExtensibilityElements(), removeList);
	
	SOAPFactory soapFactory = SOAPFactory.eINSTANCE;
	SOAPFault soapFault = soapFactory.createSOAPFault();
	soapFault.setUse((getUseOption(bindingFault) == USE_ENCODED) ? "encoded" : "literal");
	soapFault.setName(fault.getName());
//	soapFault.setNamespaceURI(getNamespace(bindingFault));

	if (getUseOption(bindingFault) == USE_ENCODED && getStyleOption(bindingFault) == STYLE_RPC)
    {
		List encodingList = new BasicEList();
		encodingList.add("http://schemas.xmlsoap.org/soap/encoding/");
		soapFault.setEncodingStyles(encodingList);
    }
	
	bindingFault.addExtensibilityElement(soapFault);
  }
  
  private String getNamespace(WSDLElement wsdlElement) {
	  if (namespaceValue.equals("") && wsdlElement != null) {
		  namespaceValue = wsdlElement.getEnclosingDefinition().getTargetNamespace();
	  }
	  if (namespaceValue == null) {
		  namespaceValue = "";
	  }
	  
	  return namespaceValue;
  }
  
  private void removeExtensebilityElements(List originalList, List removeList) {
	  Iterator removeIt = removeList.iterator();
	  while (removeIt.hasNext()) {
		  originalList.remove(removeIt.next());
	  }
  }
  
  private Binding getBindingObject(Object genericBindingObject) {
	  Object parent = genericBindingObject;
	  
	  int index = 0;
	  while (parent != null && index < 5) {
		  parent = getGenericBindingObjectParent(parent);
		  if (parent instanceof Binding) {
			  break;
		  }
		  index++;
	  }

	  return (parent instanceof Binding)? (Binding) parent : null;
  }
  
  private Object getGenericBindingObjectParent(Object genericBindingObject) {
	  Object parent = null;
	  
	  if (genericBindingObject != null) {
		  if (genericBindingObject instanceof BindingOperation) {
			  parent = ((BindingOperation) genericBindingObject).getContainer();
		  }
		  else if (genericBindingObject instanceof BindingInput) {
			  parent = ((BindingInput) genericBindingObject).getContainer();
		  }
		  else if (genericBindingObject instanceof BindingOutput) {
			  parent = ((BindingOutput) genericBindingObject).getContainer();
		  }
		  else if (genericBindingObject instanceof BindingFault) {
			  parent = ((BindingFault) genericBindingObject).getContainer();
		  }	  
	  }
	  
	  return parent;	  
  }
  
    private int getStyleOption(Object genericBindingObject) {
	  if (styleOption == OPTION_NOT_SET && genericBindingObject != null) {
		  // init() was never called, try to determine the 'style' based on what we have/know
		  Binding binding = getBindingObject(genericBindingObject);
		  
		  // Try to determine the style from the Binding Object
		  if (binding != null) {
			  List list = binding.getEExtensibilityElements();
			  Iterator valuesIt = getExtensibilityElementAttributeValue(list, "style").iterator();

			  while (valuesIt.hasNext()) {
				  String style = (String) valuesIt.next();
				  
				  if (style.equals("document")) {
					  styleOption = STYLE_DOCUMENT;
				  }
				  else if (style.equals("rpc")) {
					  styleOption = STYLE_RPC;  
				  }
				  
				  if (styleOption != OPTION_NOT_SET) {
					  break;
				  }
			  }
		  }
	  }
	  
	  if (styleOption == OPTION_NOT_SET) {
		  styleOption = STYLE_DOCUMENT;
	  }
	  
	  return styleOption;
  }
	
	  private int getUseOption(Object genericBindingObject) {
		  if (useOption == OPTION_NOT_SET) {
			  // init() was never called, try to determine the 'use' based on what we have/know
			  Iterator messageRefIt = getMessageReferenceBindingObjects(genericBindingObject).iterator();
			  
			  // Try to determine the use from the list of BindingInputs, BindingOutputs, and BindingFaults
			  while (messageRefIt.hasNext()) {
				  Object messageRef = messageRefIt.next();
				  List values = new ArrayList();
				  
				  if (messageRef instanceof BindingInput) {
					  List list = ((BindingInput) messageRef).getEExtensibilityElements();
					  values = getExtensibilityElementAttributeValue(list, "use");
				  }
				  else if (messageRef instanceof BindingOutput) {
					  List list = ((BindingOutput) messageRef).getEExtensibilityElements();
					  values = getExtensibilityElementAttributeValue(list, "use");
				  }
				  else if (messageRef instanceof BindingFault) {
					  List list = ((BindingFault) messageRef).getEExtensibilityElements();
					  values = getExtensibilityElementAttributeValue(list, "use");				  
				  }

				  Iterator valuesIt = values.iterator();
				  while (valuesIt.hasNext()) {
					  String use = (String) valuesIt.next();
					  
					  if (use.equals("literal")) {
						  useOption = USE_LITERAL;
					  }
					  else if (use.equals("encoded")) {
						  useOption = USE_ENCODED;  
					  }
				  }
				  
				  if (useOption != OPTION_NOT_SET) {
					  break;
				  }
			  }
		  }

		  if (useOption == OPTION_NOT_SET) {
			  useOption = USE_LITERAL;
		  }
		  
		  return useOption;
	  }
	  
	  private List getMessageReferenceBindingObjects(Object genericBindingObject) {
		  List list = new ArrayList();
		  Binding binding = getBindingObject(genericBindingObject);
		  
		  if (binding != null) {
			  Iterator operationsIt = binding.getEBindingOperations().iterator();
		  
			  while (operationsIt.hasNext()) {
				  BindingOperation op = (BindingOperation) operationsIt.next();
				  list.add(op.getEBindingInput());
				  list.add(op.getEBindingOutput());
				  list.addAll(op.getEBindingFaults());
			  }	  
		  }
		  
		  return list;
	  }
	
	  private List getExtensibilityElementAttributeValue(List eeList, String attributeKey) {
		  List values = new ArrayList();
		  Iterator eeElementsIt = eeList.iterator();
		  
		  while (eeElementsIt.hasNext()) {
			  ExtensibilityElement eeElement = (ExtensibilityElement) eeElementsIt.next();
			  String attributeValue = eeElement.getElement().getAttribute(attributeKey);
			  if (attributeValue != null && !attributeValue.equals("")) {
				  values.add(attributeValue);
			  }		  
		  }
		  
		  return values;
	  }
	  
	  public String getProtocol() {
		  return "SOAP";
	  }
} 