/*****************************************************************************
 * Copyright (c) 2011 Nicolas Deblock & Manuel Giles.
 *
 *
 * 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:
 * 	Nicolas Deblock  nico.deblock@gmail.com  - Initial API and implementation
 * 	Manuel Giles	 giles.manu@live.fr		 - Initial API and implementation
 * 	Cedric Dumoulin  Cedric.dumoulin@lifl.fr - Idea of the java generator project & help for the conception
 *
 *****************************************************************************/

package org.eclipse.papyrus.designer.languages.java.generator.jdtsynchronizer.impl;


import java.util.LinkedList;
import java.util.List;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.papyrus.designer.languages.java.generator.jdtsynchronizer.GeneratorPreference;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JDTJavaElement;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JDTMethod;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JDTMethodBody;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JDTParameter;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.JDTType;
import org.eclipse.papyrus.designer.languages.java.generator.metamodel.jdt.jdtmm.visitor.JDTVisitorException;


/**
 * Allow to generate Method in a IType
 *
 * @author Deblock Nicolas & Manuel Giles
 *
 */
public class SynchJDTMethod extends SynchJDTCommentable {

	protected IType itype;

	private JDTMethod method;

	private GeneratorPreference preference;

	/**
	 * Constructor
	 *
	 * @param itype
	 *            the type parent
	 */
	public SynchJDTMethod(IType itype, GeneratorPreference preference) {
		super();
		this.itype = itype;
		this.preference = preference;
	}



	@Override
	public void visit(JDTJavaElement element) throws JDTVisitorException {
		// if element can't be generated, we stop all
		if (!element.isGenerated()) {
			return;
		}

		method = (JDTMethod) element;
		// IntroduceParameterObjectDescript
		IMethod imethod = null;

		try {
			// See if the method exist
			boolean createMethod = true;

			for (IMethod m : itype.getMethods()) {
				// if it's the same name, and the same parameterTypes, the method exist
				if (m.getElementName().equals(method.getElementName()) && m.getSignature().equals(method.getJDTSignature())) {
					// stop all
					createMethod = false;
					imethod = m;
					break;
				}
			}

			if (createMethod) {
				StringBuffer methodStr = new StringBuffer("\n");

				// visibility
				if (itype.isInterface()) {
					methodStr.append("public ");
				} else {
					methodStr.append(SynchTools.getVisibility(method).toString());
				}

				// if method is a constructor, no return Type, and name is class name
				if (method.isConstructor()) {
					methodStr.append(itype.getElementName() + "(");
				}
				else {
					// return type
					if (method.getReturnType() != null) {
						// Compute the type, taken into account multivalue
						String type = getTypeAsString(method.getReturnType());
						// put the import package
						SynchTools.createImport(itype, method.getOwner(), method.getReturnType().getType());

						methodStr.append(type + " ");
					}
					else {
						methodStr.append("void ");
					}
					// method name
					methodStr.append(method.getElementName() + "(");
				}
				// parameters
				// System.out.println(method.getParam() + " " + method.getParameterTypes());
				int nbParam = 0;
				for (JDTParameter p : method.getParameters()) {
					String typeName = p.getElementName();
					String type = "Undefined";
					if (p.getType() != null) {
						// Compute the type, taken into account multivalue
						type = getTypeAsString(p);
						// put the import package
						SynchTools.createImport(itype, method.getOwner(), p.getType());
					}


					if (nbParam > 0) {
						methodStr.append(", ");
					}
					methodStr.append(type + " " + typeName);
					nbParam++;
				}

				// close
				methodStr.append(")");

				// throws
				if (method.getExceptions() != null && method.getExceptions().size() > 0) {
					methodStr.append(" throws ");
					int nbExc = 0;
					for (JDTType exception : method.getExceptions()) {
						if (nbExc > 0) {
							methodStr.append(", ");
						}
						methodStr.append(exception.getElementName());
						if (!SynchTools.isPrimiveType(exception.getQualifiedName()) && exception.getQualifiedName().contains(".")) {
							itype.getCompilationUnit().createImport(exception.getQualifiedName(), null, null);
						}
						nbExc++;
					}
				}


				// Do we need a body ?
				if (itype.isInterface() || Flags.isAbstract(method.getFlags())) {
					methodStr.append(";");
				}
				else {
					// Generate Body. Open the body
					methodStr.append(" {");
					// If there is a declared body, use it. Otherwise, use the default body.
					if (method.getBodies().size() > 0) {

						for (JDTMethodBody body : method.getBodies()) {
							methodStr.append("\n\t");
							methodStr.append(body.asText());
						}
						// methodStr.append("\n");
					}
					else {
						// Default body
						methodStr.append(" \n\t// TODO Auto-generated method");
						if (method.getReturnType() != null) {
							methodStr.append("\n\treturn " + SynchTools.defaultReturn(method.getReturnType().getType().getElementName()) + ";");
						}

					}
					// Close the body
					methodStr.append("\n }");
				}

				// create the method
				imethod = itype.createMethod(methodStr.toString(), null, true, null);
			}

			// add javadoc to method
			createJavaDocFor(imethod, imethod.getCompilationUnit(), method.getComment(), "");
			// Add explicit imports
			generateExplicitImports(method, itype);
		} catch (JavaModelException e) {
			// e.printStackTrace();
			// throw new JDTVisitorException(e.getMessage(), e.getCause());
			propagateException(e.getMessage(), e);
		} catch (Exception e) {
			// e.printStackTrace();
			// throw new JDTVisitorException(e.getMessage(), e.getCause());
			propagateException(e.getMessage(), e);
		}


	}


	/**
	 * Get the type of the parameter as a String. Take into account the multivalue setting.
	 *
	 * @param p
	 * @return
	 * @throws JavaModelException
	 */
	private String getTypeAsString(JDTParameter p) throws JavaModelException {
		String type;
		if (p.isMultiValued()) {
			type = SynchTools.getMultiValued(itype, p.getType().getElementName(), preference);
		} else {
			type = p.getType().getElementName();
		}
		return type;
	}





	/** *************** methods override by SynchJDTCommentable ************** */


	@Override
	/**
	 * search the method to insert Javadoc
	 *
	 * @see org.eclipse.papyrus.designer.languages.java.generator.jdtsynchronizer.impl.SynchJDTCommentable#searchElementToInsert(org.eclipse.jdt.core.dom.CompilationUnit, org.eclipse.jdt.core.IJavaElement)
	 *
	 * @param cu
	 * @param method
	 * @return
	 */
	protected BodyDeclaration searchElementToInsert(CompilationUnit cu, IJavaElement method) {

		// search Itype parent
		if (method.getParent() instanceof IType) {
			IType itype = (IType) method.getParent();
			// find the good type
			TypeDeclaration type = searchType((TypeDeclaration) cu.types().get(0), itype.getElementName());

			// search the method. Fortunately, there are no method getSignature() for the type MethodDeclaration.
			// So, we search manually
			for (MethodDeclaration m : type.getMethods()) {
				if (m.getName().toString().equals(method.getElementName())) {
					// verify the signature
					if (m.parameters() != null && m.parameters().size() == 0 && this.method.getParameters().size() == 0) {
						return m;
					}
					if (m.parameters().size() == this.method.getParameters().size()) {
						int numParam = 0;
						boolean goodSignature = true;
						for (Object paramObj : m.parameters()) {
							if (paramObj instanceof SingleVariableDeclaration) {
								SingleVariableDeclaration param = (SingleVariableDeclaration) paramObj;
								if (!param.getType().toString().equals(this.method.getParameters().get(numParam).getType().getElementName())) {
									goodSignature = false;
								}

								numParam++;
							}
						}
						if (goodSignature) {
							return m;
						}
					}
				}
			}
		}

		return null;
	}

	@Override
	protected List<String> getJavadocTags() {
		List<String> lst = new LinkedList<String>();
		if (method == null) {
			return lst;
		}

		// parameters
		for (JDTParameter param : method.getParameters()) {
			String comment = param.getComment();
			if (comment == null) {
				comment = "";
			}
			lst.add(TagElement.TAG_PARAM + " " + param.getElementName() + " " + comment);
		}

		// return
		if (method.getReturnType() != null) {
			String comment = method.getReturnType().getComment();
			if (comment == null) {
				comment = "";
			}
			lst.add(TagElement.TAG_RETURN + " " + comment);
		}

		// exception
		// TODO prendre en compte notion de commentaire
		if (method.getExceptions() != null) {
			for (JDTType exception : method.getExceptions()) {
				// String comment = exception.getComment();
				// if(comment == null) comment = "";
				lst.add(TagElement.TAG_THROWS + " " + exception.getElementName());
			}
		}



		return lst;
	}



	/**
	 * Propagate a {@link JDTVisitorException} if the flag is not set
	 *
	 * @param msg
	 * @param e
	 * @throws JDTVisitorException
	 */
	private void propagateException(String msg, Throwable e) throws JDTVisitorException {

		if (preference.stopOnFirstError()) {
			throw new JDTVisitorException(msg, e.getCause());
		}
		else {
			// Show error
			System.err.println(msg);
			e.printStackTrace();
		}
	}



	/**
	 * Generate imports that are explicitly declared in the type
	 *
	 * @param srcType
	 *            The src type to be transformed
	 * @param destType
	 *            The jdt dest type to be generated
	 * @throws JavaModelException
	 * @throws JDTVisitorException
	 */
	private void generateExplicitImports(JDTMethod srcType, IType destType) throws JDTVisitorException {


		// Add explicit type
		for (JDTType anImport : srcType.getExplicitRequiredImports()) {
			try {
				destType.getCompilationUnit().createImport(anImport.getQualifiedName(), null, null);
			} catch (Exception e) {
				propagateException(destType.getFullyQualifiedName() + "Can't add explicit import " + anImport.getQualifiedName(), e);
			}
		}

		// Add explicit plain text types
		for (String anImport : srcType.getExplicitPlainTextRequiredImports()) {
			try {
				destType.getCompilationUnit().createImport(anImport, null, null);
			} catch (JavaModelException e) {
				propagateException(destType.getFullyQualifiedName() + "Can't add explicit plain text import " + anImport, e);
			}
		}

	}

}
