/*******************************************************************************
 * Copyright (c) 2001, 2004 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.ui.internal.actions;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.xml.namespace.QName;

import org.eclipse.wst.wsdl.Binding;
import org.eclipse.wst.wsdl.Definition;
import org.eclipse.wst.wsdl.Fault;
import org.eclipse.wst.wsdl.Input;
import org.eclipse.wst.wsdl.Message;
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.WSDLElement;
import org.eclipse.wst.wsdl.ui.internal.WSDLEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.util.WSDLEditorUtil;
import org.eclipse.xsd.XSDElementDeclaration;
import org.w3c.dom.Node;


/*
 * This class renames 'related' WSDLElements.  The scenario is as follows:
 * The user renames a WSDLElement in the editor, say a Message.  This class
 * will find the 'related' elements to this Message and rename them as well.
 * It will only rename a 'related' element if the element name (or part of it)
 * is generated.
 * 
 * See NameUtil.java
 */
public class SmartRenameAction extends BaseNodeAction implements Runnable {
	protected Object element;
	protected String newName;
	private List messageReferences; // This variable should be accessed by method getAllMessageReferences()
	protected Node node;   
	
	public SmartRenameAction(Object element, String newName) {
		setText("Smart Rename Action"); // Do not translate
		this.element = element;
		this.newName = newName;
	    this.node = WSDLEditorUtil.getInstance().getNodeForObject(element);
	}
	
	public Node getNode() {
	   return node;
	}

	public String getUndoDescription() {
	  return WSDLEditorPlugin.getWSDLString("_UI_ACTION_RENAME");  //$NON-NLS-1$
	}

	public void run() {
		RenameAction renamer;
		String oldName;
		
		beginRecording();
		if (element instanceof Operation) {
			Operation operation = (Operation) element;
			oldName = operation.getName();

			if (oldName.equals(newName)) {
				return;
			}
			
			// Rename Operation 
			renamer = new RenameAction(operation, newName);
			renamer.run();
			
			// Rename Input
			Input input = operation.getEInput();
			/*
			if (input != null && isInputOutputNameGenerated(oldName, input.getName())) {
				renamer = new RenameAction(input, newName);
				renamer.run();
			}
			*/
			
			// Rename Output
			Output output = operation.getEOutput();
			/*
			if (output != null && isInputOutputNameGenerated(oldName, output.getName())) {
				renamer = new RenameAction(output, newName);
				renamer.run();
			}
			*/
			
			// Rename Messages and Parts
			Message msg;

			// Input
			if (input != null && input.getEMessage() != null) {
				msg = input.getEMessage();
				String oldMessageName = "";

				if (msg != null) {
					oldMessageName = msg.getQName().getLocalPart();
					
					if (isMessageNameGenerated(oldMessageName, oldName, "Request")) {
						renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName));
						
						if (msg.getEParts() != null)
							renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true);	
					}
				}
			}
			
			// Output
			if (output != null && output.getMessage() != null) {
				msg = output.getEMessage();
				String oldMessageName = "";
				
				if (msg != null) {
					oldMessageName = msg.getQName().getLocalPart();
					
					if (isMessageNameGenerated(oldMessageName, oldName, "Response")) {
						renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName));
						
						if (msg.getEParts() != null)
							renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true);
					}
					
				}
			}
			
			// Faults
			List faults = operation.getEFaults();
			if (faults != null) {
				Iterator it = faults.iterator();
				while (it.hasNext()) {
					Fault fault = (Fault) it.next();
					msg = fault.getEMessage();
					String oldMessageName = "";

					if (msg != null) {
						oldMessageName = msg.getQName().getLocalPart();
						
						if (isMessageNameGenerated(oldMessageName, oldName, fault.getName())) {
							renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName));
							
							if (msg.getEParts() != null)
								renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true);
						}
					}
				}
			}
		}
		else if (element instanceof Input) {
			Input input = (Input) element;
			oldName = input.getName();
			if (oldName == null) {
				oldName = "";
			}
			
			if (oldName.equals(newName)) {
				return;
			}
			
			input.setName(newName);

//			 Rename Messages and Parts
			Message msg;
			
			// Input
			if (input != null && input.getEMessage() != null) {
				msg = input.getEMessage();
				String oldMessageName = "";
				
				if (msg != null) {
					oldMessageName = msg.getQName().getLocalPart();
					
					if (isMessageNameGenerated(oldMessageName, oldName, "Request")) {
						renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName));
						
						if (msg.getEParts() != null)
							renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true);	
					}
				}
			}
		}
		else if (element instanceof Output) {
			Output output = (Output) element;
			oldName = output.getName();
			if (oldName == null) {
				oldName = "";
			}
			
			if (oldName.equals(newName)) {
				return;
			}
			
			output.setName(newName);

//			 Rename Messages and Parts
			Message msg;
			
			// Output
			if (output != null && output.getMessage() != null) {
				msg = output.getEMessage();
				String oldMessageName = "";
				if (msg != null) {
					oldMessageName = msg.getQName().getLocalPart();
					if (isMessageNameGenerated(oldMessageName, oldName, "Response")) {
						renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName));
						
						if (msg.getEParts() != null)
							renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true);
					}
				}
			}
		}
		else if (element instanceof Fault) {
			Fault fault = (Fault) element;
			Message msg = fault.getEMessage();
			String oldMessageName = "";
			oldName = fault.getName();
			
			if (oldName.equals(newName)) {
				return;
			}
			
			// Rename the Fault
			renamer = new RenameAction(fault, newName);
			renamer.run();

			// Rename the Message and Parts
			if (msg != null) {
				oldMessageName = msg.getQName().getLocalPart();
				
				Operation op = (Operation) fault.eContainer();
				if (isMessageNameGenerated(oldMessageName, op.getName(), oldName)) {
					renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName));
					
					if (msg.getEParts() != null)
						renameFaultParts(msg.getEParts(), op.getName(), oldName, newName);
				}
			}
		}
		else if (element instanceof Message) {
			Message msg = (Message) element;
			oldName = msg.getQName().getLocalPart();
			String oldMessageName = msg.getQName().getLocalPart();
			
			if (oldName.equals(newName)) {
				return;
			}

			renameMessageHelper(msg, computeNewMessageName(msg, oldName, newName));
					
			if (msg.getEParts() != null)
				renamePartsHelper(msg.getEParts(), oldMessageName, msg.getQName().getLocalPart(), true);
		}
		else if (element instanceof Part) {
			Part part = (Part) element;
			String oldPartName = part.getName();
			
			if (oldPartName.equals(newName)) {
				return;
			}
			
			renamer = new RenameAction(element, newName);
			renamer.run();
			
//			Rename Elements
			renameXSDElement(part, oldPartName, newName);
		}
		else if (element instanceof Port) {
			Port port = (Port) element;
			String oldPortName = port.getName();
			
			renamer = new RenameAction(element, newName);
			renamer.run();

//			Rename Binding
			Binding binding = port.getEBinding();
			if (binding != null && binding.getQName().getLocalPart().equals(oldPortName)) {
				renamer = new RenameAction(binding, newName);	
				renamer.run();
			}
		}
		endRecording();
	}
	
	// boolean isInputOutput should be set to true if the part is an Input or Output.
	// Set false if the part is a Fault.
	private void renamePartsHelper(List partsList, String oldSubString, String newSubString, boolean isInputOutput) {
		RenameAction renamer;
		
		if (partsList != null) {
			Iterator pIt = partsList.iterator();
			while (pIt.hasNext()) {
				Part part = (Part) pIt.next();
				String oldPartName = part.getName();
				
				if (isPartNameGenerated(oldPartName, oldSubString)) {
					String newPartName;
					if (isInputOutput) {
						newPartName = computeNewPartName(part, oldSubString, newSubString);
					}
					else {
						newPartName = computeNewFaultPartName(part, oldSubString, newSubString);
					}
					
					renamer = new RenameAction(part, newPartName);
					renamer.run();
					
					// Rename Elements
					renameXSDElement(part, oldPartName, newPartName);
				}
			}
		}
	}
	
	// This method is used to update the Part name when the Fault name is changed.  Only
	// change the Part name if the part name is a generated name.
	// Compare to renamePartsHelper().  The renamePartsHelper() method is called when a Fault
	// has NOT been renamed, rather, it is triggered by some other naming (ex. Operation
	// renaming).  It will updat Input/Output, AND Fault Parts.
	private void renameFaultParts(List partsList, String baseName, String oldSubString, String newSubString) {
		RenameAction renamer;
		
		if (partsList != null) {
			Iterator pIt = partsList.iterator();
			while (pIt.hasNext()) {
				Part part = (Part) pIt.next();
				String oldPartName = part.getName();
				
				if (isPartNameGenerated(oldPartName, baseName, oldSubString)) {
					String newPartName;
					newPartName = computeNewFaultPartName(part, oldSubString, newSubString);
					renamer = new RenameAction(part, newPartName);
					renamer.run();
					
					// Rename Elements
					renameXSDElement(part, oldPartName, newPartName);
				}
			}
		}
	}
	
	private String computeNewMessageName(Message message, String oldSubString, String newSubString) {
		String string = message.getQName().getLocalPart();
		return replaceSectionWithSubString(string, oldSubString, newSubString, 0);		
	}
	
//	private String computeNewFaultMessageName(Message message, String oldSubString, String newSubString) {
//		String string = message.getQName().getLocalPart();
//		return replaceSectionWithSubString(string, oldSubString, newSubString, 1);		
//	}
	
	// Method for Input, Output, and Fault Parts
	// See computeNewFaultPartName() for comparison
	private String computeNewPartName(Part part, String oldSubString, String newSubString) {
		String string = part.getName();
		return replaceSectionWithSubString(string, oldSubString, newSubString, 0);		
	}
	
	// Method for Fault Parts
	// This method behaves in the exact same way as computeNewPartName() except it starts searching for a match
	// after the first character.  This method is intended for users who wish to rename a generated (Fault) part
	// where the Fault name has changed.  We start our search after the first character because the generated name
	// of the part is built by appending the Fault name after the Operation name.
	private String computeNewFaultPartName(Part part, String oldSubString, String newSubString) {
		String string = part.getName();
		return replaceSectionWithSubString(string, oldSubString, newSubString, 1);		
	}
	
	private String replaceSectionWithSubString(String fullString, String oldSubString, String newSubString, int startSearchIndex) {
		StringBuffer fullSB = new StringBuffer(fullString);
		int index = fullSB.indexOf(oldSubString, startSearchIndex);
		if (index >= 0) {
			return fullSB.replace(index, index + oldSubString.length(), newSubString).toString();
		}
		
		return "";
	}

	////////////////////////////////////////////////////////////////////////////////////////
	
	private static boolean commonNameGeneratorCheck(String targetName, String baseName, String appendName) {
		// First criteria is targetName must start with the baseName
		if (!targetName.startsWith(baseName))
			return false;
			
		if (appendName.trim().length() > 0) {
			// Second criteria.  The appended name must be in the targetName and begin right
			// after the baseName location
			if (!targetName.startsWith(appendName, baseName.length()))
				return false;
		}
			
		// Third criteria (if necessary).  If baseName + appendName is shorter than targetName,
		// then there must be 'extra' characters at the end of targetName.  These characters must
		// make up an integer.  If not, it is not a generated string.
		int subLength = baseName.length() + appendName.length();
		if (targetName.length() > subLength) {
			// We have 'extra' characters
			String extras = targetName.substring(subLength);
			
			if(!isDigit(extras))
				return false;
		}
		
		return true;
	}
	
	public static boolean isOperationNameGenerated(String opName, String name) {
		return opName.equals(name);
	}
	
	public static boolean isMessageNameGenerated(String msgName, String baseName, String appendName) {
		return commonNameGeneratorCheck(msgName, baseName, appendName);
	}
	
	public static boolean isInputOutputNameGenerated(String inOutName, String name) {
		return inOutName.equals(name);
	}
	
	public static boolean isFaultNameGenerated(String faultName, String name) {
		return faultName.equals(name);
	}
	
	public static boolean isPartNameGenerated(String partName, String baseName) {
		return commonNameGeneratorCheck(partName, baseName, "");
	}
	
	private boolean isPartNameGenerated(String partName, String baseName, String appendName) {
		return commonNameGeneratorCheck(partName, baseName, appendName);
	}
	
	private static boolean isDigit(String string) {
		boolean rValue = true;
		char[] chars = string.toCharArray();
	
		for (int index = 0; index < chars.length; index++) {
			if (!Character.isDigit(chars[index])) {
				rValue = false;
				break;
			}
		}
		
		return rValue;
	}
	
	/*
	 * The following classes aid in renaming a message
	 */
	private void renameMessageHelper(Message msg, String newName) {
		List messageRefs = getReferencingMessageReferences(msg, getAllMessageReferences());
		
		RenameAction renamer = new RenameAction(msg, newName);
		renamer.run();
		
		Iterator iterator = messageRefs.iterator();
		while (iterator.hasNext()) {
			MessageReference messageReference = (MessageReference) iterator.next();
			messageReference.setEMessage(msg);
		}
	}
	
	private List getReferencingMessageReferences(Message msg, List messageRefs) {
		Vector referencesVector = new Vector();
		QName messageQName = msg.getQName();
		Iterator iterator = messageRefs.iterator();
		
		while (iterator.hasNext()) {
			MessageReference messageReference = (MessageReference) iterator.next();
			if (messageReference.getEMessage() != null && messageQName.equals(messageReference.getEMessage().getQName())) {
				referencesVector.addElement(messageReference);
			}
		}
		
		return referencesVector;
	}
	
	private List getAllMessageReferences() {
		if (messageReferences == null) {
			messageReferences = new Vector();
			Definition definition = ((WSDLElement) element).getEnclosingDefinition();
			List portTypes = definition.getEPortTypes();
		
			if (portTypes != null) {
				Iterator portTypeIterator = portTypes.iterator();
				while (portTypeIterator.hasNext()) {
					List operationsList = ((PortType) portTypeIterator.next()).getEOperations();
					
					if (operationsList != null) {
						Iterator operationsIterator = operationsList.iterator();
						while (operationsIterator.hasNext()) {
							messageReferences.addAll(getAllMessageReferences((Operation) operationsIterator.next()));
						}
					}
				}
			}
		}
		
		return messageReferences;
	}
	
	private Vector getAllMessageReferences(Operation operation) {
		Vector iofs = new Vector();
		Iterator it = operation.getEFaults().iterator();
		while (it.hasNext()) {
			iofs.addElement(it.next());
		}
		
		if (iofs == null)
			iofs = new Vector();
		
		if (operation.getEInput() != null)
			iofs.addElement(operation.getEInput());
		
		if (operation.getEOutput() != null)
			iofs.addElement(operation.getEOutput());
		
		return iofs;
	}
	
	private void renameXSDElement(Part part, String oldXSDName, String newXSDName) {
		XSDElementDeclaration elementDeclaration = part.getElementDeclaration();
		if (elementDeclaration != null && oldXSDName.equals(elementDeclaration.getName())) {
			renameElementDeclarationHelper(elementDeclaration, oldXSDName, newXSDName);
			
			// Here we rename the element reference.
			//
			QName qname = new QName(part.getElementName().getNamespaceURI(), newXSDName);
			part.setElementName(qname);			
		}
	}
	
	private void renameElementDeclarationHelper(XSDElementDeclaration elementDeclaration, String oldXSDName, String newXSDName) {
		if (elementDeclaration != null && elementDeclaration.getName().equals(oldXSDName)) {
			elementDeclaration.setName(newXSDName);
		}
	}
	
}
