/*******************************************************************************
 * Copyright (c) 2000, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common 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.internal.generator;

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

import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Import;
import org.eclipse.wst.wsdl.Port;
import org.eclipse.wst.wsdl.Service;
import org.eclipse.wst.wsdl.WSDLFactory;

public class PortGenerator extends BaseGenerator {
	private Service service;
	
    /**
     * Constructs a port generator given the target service.
     * @param service the target Service, must not be null.
     */
	public PortGenerator(Service service) {
		this.service = service;
		definition = service.getEnclosingDefinition();
	}
	
    /**
     * Generates a service port given it's name and binding name.
     * The port is then added to the service passed in the constructor.
     * @return the Port instance
     */
	public Port generatePort() {
	  String portName = getName();
	  String bindingName = getRefName();		
	  
	  Binding binding = getBinding(bindingName);
	  
	  Port port = WSDLFactory.eINSTANCE.createPort();
	  port.setName(portName);
	  port.setEnclosingDefinition(definition);
	  port.setBinding(binding);
	  
	  service.addPort(port);
	  
	  ContentGenerator contentGenerator = getContentGenerator(); 
	  
	  if (contentGenerator != null) {
		  addRequiredNamespaces(service.getEnclosingDefinition());
	      contentGenerator.generatePortContent(port);
	  }
	  
	  return port;
	}
	
	/*
	 * methods addRequiredNamespaces() and computeUniquePrefix() are used to add necessary
	 * namespaces 
	 * 
	 * TODO:
	 * Does this belong here?  This is copied from wsdl.ui.  Can we sync up in some way?
	 */
	protected void addRequiredNamespaces(Definition definition) {
		if (contentGenerator != null) {
			String[] namespaceNames = contentGenerator.getRequiredNamespaces();
			String[] preferredPrefixes = new String[namespaceNames.length];
			for (int index = 0; index < namespaceNames.length; index++) {
				preferredPrefixes[index] = contentGenerator.getPreferredNamespacePrefix(namespaceNames[index]);				
			}
	
			Map map = definition.getNamespaces();
			
		      for (int i = 0; i < namespaceNames.length; i++) {
		        String namespace = namespaceNames[i];
		        if (!map.containsValue(namespace)) {
		          String prefix = (i < preferredPrefixes.length) ? preferredPrefixes[i] : "p0";
		          if (map.containsKey(prefix)) {
		            prefix = computeUniquePrefix("p", map);
		          }
				  definition.addNamespace(prefix, namespace);
		        }
		      }
		}
	}
	
	private String computeUniquePrefix(String base, Map table){
	    int i = 0;
	    String prefix = base;
	    while (true) {
	      if (!table.containsKey(prefix)) {
	        break;
	      }
	      else {
	        prefix = base + i;
	        i++;
	      }
	    }
	    return prefix;
	}
	
	/**
	 * Locates a binding given its prefixed name (someNSPrefix:someBindingName).
	 * 
	 * @param bindingName the qname of the desired binding.
	 * @return a Binding with the given name, or null if one is not found.
	 */
	private Binding getBinding(String bindingName) {
      List allBindings = getAllBindings();
      Iterator bindingIterator = allBindings.iterator();
	  
	  while (bindingIterator.hasNext()) {
	    Binding binding = (Binding)bindingIterator.next();
	    
	    List prefixedNames = getPrefixedNames(binding);
	    
	    if (prefixedNames.contains(bindingName)) {
	      return binding;
	    }
	  }
	  
	  return null;
	}
	
	/**
	 * Locates all the bindings available in this definition and all its
	 * imported definitions.
	 * 
	 * @return a List with all available bindings.
	 */
	public List getAllBindings() {
	  List allBindings = new ArrayList();
	  List allDefinitions = getAllDefinitions();
	  
	  Iterator defsIterator = allDefinitions.iterator();
	  
	  while (defsIterator.hasNext()) {
	    Definition definition = (Definition) defsIterator.next();
	    Map bindings = definition.getBindings();
	    
	    // ISSUE A possible problem here if somehow a binding is duplicated in one of the imports?
	    // In that case we should iterate over and check them one by one.
	    
	    allBindings.addAll(bindings.values());
	  }
	  
	  return allBindings;
	}
	
	/**
	 * Attempts to locate and add to the list all the definitions imported by the
	 * definition passed in. Recursively tries to locate all definitions.
	 * 
	 * @param definition the start Definition. Must not be null.
	 * @param list used to collect all the imported definitions. Must not be null.
	 */
	private void addDefinition(Definition definition, List list) {
	  list.add(definition);
	  List imports = definition.getEImports();
	  Iterator importsIterator = imports.iterator();
	  
	  while (importsIterator.hasNext()) {
	    Import theImport = (Import)importsIterator.next();
	    
	    String importLocationURI = theImport.getLocationURI();
	    if (importLocationURI != null && 
	        // ISSUE This assumption seems a bit weak.
            importLocationURI.endsWith("wsdl")) {
	      Definition importedDefinition = theImport.getEDefinition();
	      
	      if (importedDefinition != null && 
              !list.contains(importedDefinition)) {
	        // Recursively try to locate all definitions.

            addDefinition(importedDefinition, list);
	      }
	    }
	  }
	}
	
	/**
	 * Attempts to locate all definitions imported by the current definition and
     * all their imports in turn. 
	 * 
	 * @return a List with all definitions imported by the current definition.
	 */
	private List getAllDefinitions()
	{
	  List list = new ArrayList();
	  addDefinition(definition, list);
	  return list;
	}
	
	private List getPrefixedNames(Binding binding) {
		List prefixedNames = new ArrayList();
		String currentBindingName = binding.getQName().getLocalPart();
		String currentNamespace = binding.getQName().getNamespaceURI();

		Map namespaceMap = definition.getNamespaces();
		Iterator keys = namespaceMap.keySet().iterator();
		while (keys.hasNext()) {
			Object key = keys.next();
			Object value = namespaceMap.get(key);
			
			if (currentNamespace.equals(value)) {
				// Found a match.  Add to our list
				prefixedNames.add(key + ":" + currentBindingName); //$NON-NLS-1$
			}
		}
		
		return prefixedNames;
	}
	
	public Service getService() {
		return service;
	}
}
