/*******************************************************************************
 * Copyright (c) 2016 CEA LIST
 * 
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License 2.0 which
 * accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *   Shuai Li (CEA LIST) <shuai.li@cea.fr> - Initial API and implementation
 *   Van Cam Pham (CEA LIST) <vancam.pham@cea.fr> - Reverse implementation
 *   Ansgar Radermacher (CEA LIST) - Larger refactoring
 *******************************************************************************/

package org.eclipse.papyrus.designer.languages.cpp.reverse.reverse

import java.util.ArrayList
import java.util.List
import java.util.regex.Matcher
import java.util.regex.Pattern
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition
import org.eclipse.cdt.core.dom.ast.IASTNode
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter
import org.eclipse.cdt.core.model.IMethodDeclaration
import org.eclipse.cdt.core.model.IMethodTemplateDeclaration
import org.eclipse.cdt.core.parser.IToken
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.Const
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.ConstInit
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.Friend
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.Inline
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.Variadic
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.Virtual
import org.eclipse.papyrus.designer.languages.cpp.profile.C_Cpp.Volatile
import org.eclipse.papyrus.designer.uml.tools.utils.StereotypeUtil
import org.eclipse.uml2.uml.Class
import org.eclipse.uml2.uml.OpaqueBehavior
import org.eclipse.uml2.uml.Operation
import org.eclipse.uml2.uml.ParameterDirectionKind
import org.eclipse.uml2.uml.Type
import org.eclipse.uml2.uml.UMLPackage
import org.eclipse.uml2.uml.profile.standard.Create
import org.eclipse.uml2.uml.profile.standard.Destroy
import org.eclipse.uml2.uml.util.UMLUtil

import static extension org.eclipse.papyrus.designer.languages.cpp.reverse.reverse.ASTUtils.*
import static extension org.eclipse.papyrus.designer.languages.cpp.reverse.reverse.ReverseUtils.*

/**
 * functions to create and update methods
 */
class MethodUtils {
	/**
	 * Create a UML operation from a CDT method declaration
	 */
	static def createMethod(IMethodDeclaration method, Class classifier) {
		var IASTFunctionDeclarator declarator = method.declarator
		if (declarator !== null) {
			val op = classifier.createOwnedOperation(method.elementName, null, null)
			op.setXmlID
			updateMethod(classifier, op, method)
		}
	}

	/**
	 * Update an existing operation from a CDT method declaration
	 */
	static def updateMethod(Class classifier, Operation op, IMethodDeclaration method) {
		op.name = method.elementName
		StereotypeUtil.unapply(op, Inline)
		StereotypeUtil.unapply(op, Friend)
		StereotypeUtil.unapply(op, Virtual)
		StereotypeUtil.unapply(op, Volatile)
		StereotypeUtil.unapply(op, Create)
		StereotypeUtil.unapply(op, Destroy)
		StereotypeUtil.unapply(op, Const)
		op.ownedParameters.clear
		var List<String> keywords = method.keywords
		var body = method.body

		op.visibility = method.visibility.convertVisibility
		op.isStatic = method.isStatic
		op.applyStereotype(method.inline, Inline)
		op.applyStereotype(method.friend, Friend)
		op.applyStereotype(method.isVirtual, Virtual)
		op.applyStereotype(method.volatile, Volatile)
		op.applyStereotype(method.isConst, Const)
		if (method.isVirtual) {
			if (method.pureVirtual) {
				op.isAbstract = true
			}
		}
		op.applyStereotype(method.constructor, Create)
		op.applyStereotype(method.destructor, Destroy)
		try {
			var String signature = method.signature
			var Pattern pattern = Pattern.compile("([\\s]*)(\\.\\.\\.)([\\s]*)(\\))");
			var Matcher matcher = pattern.matcher(signature);
			op.applyStereotype(matcher.find(), Variadic)
		} catch (Exception e) {
			e.printStackTrace
		}

		if (method instanceof IMethodTemplateDeclaration) {
			for (var i = 0; i < method.templateParameterTypes.size; i++) {
				GetOrCreateP1.getOrCreateTemplateParameter(op, method.templateParameterTypes.get(i), keywords.get(i))
			}
		}
		var declSpecifier = method.declSpecifier
		var declarator = method.declarator
		if (!method.constructor && !method.destructor) {
			if (method.returnType !== null) {
				var parameterType = op.getParameterTemplateType(method, declSpecifier.qualifiedName)
				if (parameterType === null) {
					parameterType = declSpecifier.qualifiedName.getUMLType(method)
				}
				var ret = op.createOwnedParameter("ret", parameterType)
				ret.direction = ParameterDirectionKind.RETURN_LITERAL
				declarator.analyzeDeclaration(ret.type, ret, Cpp_LangID)
				PkgDependencies.createDependency(classifier, ret.type)

				if (parameterType !== null && parameterType.name.equals("void") && ret.appliedStereotypes.empty) {
					ret.destroy
				}

				ret.applyStereotype(declSpecifier.isConst, Const)
				ret.applyStereotype(declSpecifier.isVolatile, Volatile)
			} else {
				var ret = op.createOwnedParameter("ret", "void".getUMLType(method))
				ret.direction = ParameterDirectionKind.RETURN_LITERAL
				declarator.analyzeDeclaration(ret.type, ret, Cpp_LangID)
				if (ret.appliedStereotypes.empty) {
					ret.destroy
				}
			}
		}

		for (param : declarator.parameters) {
			var parameterType = op.getParameterTemplateType(method, param.declSpecifier.getCppTypeName())
			if (parameterType === null) {
				parameterType = param.declSpecifier.getUMLType(method)
			}
			val opParam = op.createOwnedParameter(param.declarator.name.toString, parameterType)
			opParam.applyStereotype(param.declSpecifier.const, Const)
			param.declarator.analyzeDeclaration(opParam.type, opParam, Cpp_LangID)
			opParam.applyStereotype(param.declSpecifier.volatile, Volatile)
		}

		if (body !== null) {
			if (method.constructor) {
				var initStr = method.memberInit
				if (!initStr.empty) {
					StereotypeUtil.apply(op, ConstInit)
					UMLUtil.getStereotypeApplication(op, ConstInit).initialisation = initStr
				}
			}
			var OpaqueBehavior ob = null;
			if (op.getMethods().size() == 0) {
				ob = classifier.createOwnedBehavior(op.name, UMLPackage.Literals.OPAQUE_BEHAVIOR) as OpaqueBehavior
				ob.setSpecification(op)
				ob.setIsReentrant(false)
			} else {
				ob = op.getMethods().get(0) as OpaqueBehavior
				if (!ob.getName().equals(op.name)) {
					ob.setName(op.name);
				}
			}

			if (ob.getBodies().size() == 0) {
				ob.getLanguages().add(Cpp_LangID)
				ob.getBodies().add("")
			}

			for (var i = 0; i < ob.getLanguages().size(); i++) {
				if (ob.getLanguages().get(i).equals(Cpp_LangID)) {
					if (i < ob.getBodies().size()) {
						ob.getBodies().set(i, body)
					}
				}
			}

			val IASTNode node = method.findEnclosingNode

			if (node instanceof IASTFunctionDefinition) {
				// new DependencyAnalysis(op, node, method.translationUnit).analyzeDependencies();
			}
		}
	}
	
	static def Type getParameterTemplateType(Operation op, IMethodDeclaration imethod, String typeName) {
		var Type ret = null
		if (imethod instanceof IMethodTemplateDeclaration) {
			if (!imethod.templateParameterTypes.filter[it.equals(typeName)].empty) {
				ret = GetOrCreateP1.getOrCreateTemplateParameter(op, typeName, "class")
			}
		}
		return ret
	}
	
		static def List<String> getKeywords(IMethodDeclaration method) {
		var node = method.findEnclosingNode
		var List<String> keywords = new ArrayList
		if (node instanceof ICPPASTTemplateDeclaration) {
			for (child : node.children) {
				if (child instanceof ICPPASTTemplateParameter) {
					var token = child.syntax
					var keyword = "class"
					while (token !== null) {
						if (token.type == IToken.t_typename) {
							keyword = "typename"
						}
						token = token.next
					}
					keywords.add(keyword)
				}
			}
		}
		return keywords
	}

	static def String getBody(IMethodDeclaration method) {
		var IASTFunctionDeclarator declarator = null
		var node = method.findEnclosingNode
		var String body = null

		if (node instanceof ICPPASTFunctionDefinition) {
			declarator = (node as ICPPASTFunctionDefinition).declarator
			body = BatchReverseFunctionBody.getBody(method.translationUnit, node as ICPPASTFunctionDefinition)
		} else if (node instanceof IASTFunctionDeclarator) {
			// TODO
		}

		// TODO
		/*if (body === null) {
		 * 	if (method.translationUnit.isHeaderUnit) {
		 * 		val headerUnitNameNoExtension = method.translationUnit.elementName.substring(0, method.translationUnit.elementName.lastIndexOf('.'))
		 * 		
		 * 		for (ICContainer container : containers) {
		 * 			var children = container.children
		 * 			container.children.filter(typeof(ITranslationUnit)).filter[!it.isHeaderUnit].forEach [
		 * 				val sourceUnitNameNoExtension = it.elementName.substring(0, it.elementName.lastIndexOf('.'))
		 * 				if (sourceUnitNameNoExtension.equals(headerUnitNameNoExtension)) {
		 * 					var unit = it
		 * 					unit.
		 * 					println(unit)
		 * 				}
		 * 			]
		 * 		}
		 * 	}iTu l
		 }*/
		return body
	}
	
}
