/*******************************************************************************
 * Copyright (c) 2013 THALES GLOBAL SERVICES 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.emf.ecoretools.design.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcoreFactory;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

/**
 * Services dealing with EOperations usable from a VSM.
 */
public class EOperationServices {
	private static final String TYPE_SEPARATOR = ":";

	private static final String PARAMETERS_SEPARATOR = ",";

	/**
	 * Computes the label of an EOperation.
	 */
	public String render(EOperation op) {
		StringBuilder sb = new StringBuilder();
		renderName(op, sb);
		renderParameters(op, sb, true);
		renderType(op, sb);
		return sb.toString();
	}

	/**
	 * Computes the tooltip of an EOperation (same as label but excluding the
	 * parameters Types) .
	 * 
	 * @param op
	 *            the operation to be rendered
	 * @return the tooltip of the given EOperation (same as label but excluding
	 *         the parameters Types)
	 */
	public String renderEOperationTooltip(EOperation op) {
		StringBuilder sb = new StringBuilder();
		renderName(op, sb);
		renderParameters(op, sb, false);
		renderType(op, sb);
		return sb.toString();
	}

	/**
	 * Performs a "direct edit" operation on an EOperation.
	 */
	public EOperation performEdit(EOperation op, String editString) {
		editName(op, editString);
		editParameters(op, editString);
		editType(op, editString);
		return op;
	}

	private void renderName(EOperation op, StringBuilder sb) {
		if (op.getName() != null) {
			sb.append(op.getName());
		}
	}

	/**
	 * Renders the parameters of the given EOperation.
	 * 
	 * @param op
	 *            the operation to render
	 * @param sb
	 *            the string builder used to render the eOperation
	 * @param includeParameterType
	 *            indicates whether parameter's Types should be rendered or not
	 */
	private void renderParameters(EOperation op, StringBuilder sb,
			boolean includeParameterType) {
		sb.append("(");
		boolean first = true;
		for (EParameter param : op.getEParameters()) {
			if (!first) {
				sb.append(PARAMETERS_SEPARATOR).append(" ");
			} else {
				first = false;
			}
			sb.append(renderParameter(param, includeParameterType));
		}
		sb.append(")");
	}

	/**
	 * Renders the given Parameter.
	 * 
	 * @param parameter
	 *            the parameter to render
	 * @param includeParameterType
	 *            indicates whether parameter's Type should be rendered or not
	 */
	private String renderParameter(EParameter parameter,
			boolean includeParameterType) {
		String name = parameter.getName();
		String typeName = EGenericsServices.getETypeLabel(parameter);
		if (name != null && typeName != null && includeParameterType) {
			return parameter.getName() + " " + typeName;
		} else if (name != null) {
			return parameter.getName();
		} else {
			return "";
		}
	}

	private void renderType(EOperation op, StringBuilder sb) {
		String typeLabel = EGenericsServices.getETypeLabel(op);
		if (typeLabel != null) {
			sb.append(" ").append(TYPE_SEPARATOR).append(" ");
			sb.append(typeLabel);
		}
	}

	private void editName(EOperation op, String editString) {
		int nameEnd = editString.length();
		int typeStart = editString.indexOf(TYPE_SEPARATOR);
		if (typeStart != -1) {
			nameEnd = Math.min(nameEnd, typeStart);
		}
		int paramStart = editString.indexOf("(");
		if (paramStart != -1) {
			nameEnd = Math.min(nameEnd, paramStart);
		}

		String namePart = editString.substring(0, nameEnd);
		if (namePart.trim().length() > 0) {
			op.setName(namePart.trim());
		} else if (typeStart == -1 && paramStart == -1) {
			// Reset the name only if no other parts have been specified.
			op.setName(null);
		}
	}

	private void editParameters(EOperation op, String editString) {
		int paramStart = editString.indexOf("(");
		int paramEnd = editString.lastIndexOf(")");
		if (paramStart != -1 && paramEnd != -1 && paramStart < paramEnd) {
			List<String[]> spec = parseParameters(editString.substring(
					paramStart + 1, paramEnd));
			int nbParam = spec.size();
			// Remove parameters from the end if we have too many.
			for (int i = op.getEParameters().size() - 1; i >= nbParam; i--) {
				op.getEParameters().remove(i);
			}
			// Update existing parameters with new spec and append additional
			// ones if necessary
			for (int i = 0; i < nbParam; i++) {
				EParameter param = null;
				if (i < op.getEParameters().size()) {
					param = op.getEParameters().get(i);
				} else {
					param = EcoreFactory.eINSTANCE.createEParameter();
					op.getEParameters().add(param);
				}
				updateParameter(op, param, spec.get(i));
			}
		}
	}

	private void updateParameter(EOperation op, EParameter param,
			String[] paramSpec) {
		if (paramSpec[0] != null) {
			param.setName(paramSpec[0]);
		}
		if (paramSpec[1] != null) {
			EClassifier type = new DesignServices().findTypeByName(op,
					paramSpec[1]);
			if (type != null) {
				param.setEType(type);
			}
		}
	}

	private List<String[]> parseParameters(String spec) {
		List<String[]> result = new ArrayList<String[]>();
		if (spec.contains(PARAMETERS_SEPARATOR)) {
			String[] params = spec.split(PARAMETERS_SEPARATOR);
			for (String paramSpec : params) {
				result.add(parseParameter(paramSpec));
			}
		} else if (spec.trim().length() > 0) {
			result.add(parseParameter(spec));
		}
		return result;
	}

	/**
	 * Parses a single parameter specification. Supports the following syntaxes:
	 * 
	 * <pre>
	 * "name"
	 * "name Type"
	 * "name : Type"
	 * " : Type"
	 * </pre>
	 * 
	 * Returns an array of two strings, representing the parameter name and the
	 * type name. Both can be <code>null</code> if the corresponding part is not
	 * specified.
	 * 
	 * Note: this method is public only so that it can be visible from tests.
	 */
	public String[] parseParameter(String paramSpec) {
		String[] type = null;
		// Try ":" as type separator
		int typeStart = paramSpec.indexOf(TYPE_SEPARATOR);
		if (typeStart != -1) {
			type = splitParameterSpec(paramSpec, typeStart);
		} else {
			// If there is no ":", assume whitespace separates the name from the
			// type
			paramSpec = paramSpec.trim();
			typeStart = paramSpec.lastIndexOf(" ");
			if (typeStart != -1) {
				type = splitParameterSpec(paramSpec, typeStart);
			} else {
				typeStart = paramSpec.lastIndexOf("\t");
				if (typeStart != -1) {
					type = splitParameterSpec(paramSpec, typeStart);
				}
			}
		}
		// If there was neither ":" nor space, the spec can specify only the
		// name, or maybe nothing if it is blank.
		if (type == null) {
			String name = paramSpec.trim();
			if (name.length() == 0) {
				name = null;
			}
			type = new String[] { name, null };
		}
		return type;
	}

	public List<ENamedElement> getAllAssociatedElements(EOperation op) {
		// [eParameters->including(self)->asSequence()->sortedBy(name)/]
		List<ENamedElement> result = Lists.newArrayListWithExpectedSize(1 + op
				.getEParameters().size());
		result.add(op);
		result.addAll(op.getEParameters());
		Collections.sort(
				result,
				Ordering.natural().onResultOf(
						new Function<ENamedElement, String>() {
							public String apply(ENamedElement input) {
								return input.getName();
							}
						}));
		return result;
	}

	private String[] splitParameterSpec(String paramSpec, int typeStart) {
		String[] type;
		String name;
		String typeName;
		name = paramSpec.substring(0, typeStart).trim();
		if (typeStart != paramSpec.length() - 1) {
			typeName = paramSpec.substring(typeStart + 1).trim();
		} else {
			typeName = null;
		}
		if (name.length() == 0) {
			name = null;
		}
		if (typeName != null && typeName.length() == 0) {
			typeName = null;
		}
		type = new String[] { name, typeName };
		return type;
	}

	private void editType(EOperation op, String editString) {
		Object value = getSpecifiedType(op, editString);
		if (value != null) {
			EGenericsServices.setETypeWithGenerics(op, value);
		} else {
			// Only reset the type to null if the ":" is explicitly present with
			// no type specified
			int typeStart = editString.lastIndexOf(TYPE_SEPARATOR);
			if (typeStart != -1
					&& !editString.substring(typeStart).contains(")")) {
				op.setEType(null);
			}
		}
	}

	private Object getSpecifiedType(ETypedElement receiver, String editString) {
		int typeStart = editString.lastIndexOf(TYPE_SEPARATOR);
		if (typeStart != -1 && editString.length() > typeStart + 1) {
			String typeName = editString.substring(typeStart + 1).trim();
			if (!typeName.contains(")")) {
				Object value = EGenericsServices.findGenericType(receiver,
						typeName);
				if (value == null) {
					value = new DesignServices().findTypeByName(receiver,
							typeName);
				}
				return value;
			}
		}
		return null;
	}
}
