package org.eclipse.papyrus.designer.languages.c.codegen.lib

import java.util.ArrayList
import java.util.List
import org.eclipse.papyrus.designer.languages.c.codegen.preferences.CCodeGenConstants
import org.eclipse.papyrus.designer.languages.common.base.GenUtils
import org.eclipse.uml2.uml.CallEvent
import org.eclipse.uml2.uml.Class
import org.eclipse.uml2.uml.Event
import org.eclipse.uml2.uml.OpaqueBehavior
import org.eclipse.uml2.uml.OpaqueExpression
import org.eclipse.uml2.uml.Region
import org.eclipse.uml2.uml.State
import org.eclipse.uml2.uml.StateMachine
import org.eclipse.uml2.uml.Transition
import org.eclipse.uml2.uml.Vertex
import org.eclipse.uml2.uml.FinalState
import java.util.regex.Pattern

class stateMachineScript {

	static List<Transition> transitions = new ArrayList
	public static Region region
	public List<State> states = new ArrayList
	List<Vertex> vertexes = new ArrayList
	public static String ACTIVE_ROOT_STATE_ID = "activeStateID"

	def static genProcessCompletionEventMethodBody(Class clazz) {
		
		region = clazz.ownedBehaviors.filter(StateMachine).head.regions.head;
		transitions.addAll(region.transitions.filter[it.source !== null && it.target !== null])
		val NonTriggeredTrans = new ArrayList<Transition>
		transitions.forEach [
			if (it.source instanceof State && ! (it.target instanceof FinalState) && (it.triggers.map[it.event].size == 0)) {
						NonTriggeredTrans.add(it)	
			}

		]
		val sources = NonTriggeredTrans.map[it.source].filter(State).toSet;
		val setTransitions= NonTriggeredTrans.toSet;
		var body = '''
			
			«IF NonTriggeredTrans.size > 0»		
				switch(self->«ACTIVE_ROOT_STATE_ID») {
									«FOR state:sources»
										case «state.name»: 
											«FOR t:setTransitions»	
												«IF t.source==state»
													«generateTransitionCode(t.source as State, t)»
												«ENDIF»
											«ENDFOR»
											{}
										
										break;
									«ENDFOR»
									default:
									//do nothing
									break;
				}
			«ENDIF»
			
		'''
		return body
	}

	def static genProcessMethodBody(Event callevent, Class clazz) {

		region = clazz.ownedBehaviors.filter(StateMachine).head.regions.head;
		transitions.addAll(region.transitions.filter[it.source !== null && it.target !== null])
		val TriggeredTrans = new ArrayList<Transition>
		transitions.forEach [
			if (it.source instanceof State && !(it.triggers.map[it.event].size == 0)) {
				var events = it.triggers.map[it.event].toList;
				if (events.contains(callevent)) {
					if (!TriggeredTrans.contains(it)) {
						TriggeredTrans.add(it)
					}
				}
			}

		]
		val sources = TriggeredTrans.map[it.source].filter(State).toSet;

		var body = '''
			
			«IF TriggeredTrans.size > 0»		
				switch(self->«ACTIVE_ROOT_STATE_ID») {
									«FOR state:sources»
										case «state.name»: 
											«FOR t:TriggeredTrans »	
												«IF t.source==state»
													«generateTransitionCode(t.source as State, t)»
												«ENDIF»
											«ENDFOR»
											{}
											
										break;
									«ENDFOR»
									default:
									//do nothing
									break;
				}
			«ENDIF»
			
		'''
		return body
	}

	def static String generateTransitionCode(State s, Transition t) {
		var ret = ''''''
		val cGuard = getGuard(t)
		val acslGuard = acslScript.getGuard(t)
		if (t.target instanceof State) {
			ret = '''
			/*  transition guard */
			«IF !acslGuard.empty»«acslGuard»«ENDIF»
			if («IF !cGuard.empty»«cGuard»«ELSE»1«ENDIF») {
				/* exit Transition source */
				if (self->states[«t.source.getName()»].exit != NULL) {
					self->states[«t.source.getName()»].exit();
				}
				
				/* transition effect*/
				«t.getTransitionEffect»
				
				/* update current state */
				self->«ACTIVE_ROOT_STATE_ID» = «t.target.getName()» ;
				
				/* entry of the new state */
				if (self->states[«t.target.getName()»].entry != NULL) {
					self->states[«t.target.getName()»].entry();
				}
				
				/* doActivity of the new state */
				if (self->states[«t.target.getName()»].doActivity != NULL) {
					self->states[«t.target.getName()»].doActivity();
				}
				
				/* always call process completion event to handle completion transition */
				ProcessCompletionEvent(self);
			} else'''
		}
		return ret
	}

	def static String getTransitionEffect(Transition t) {
		if (t.effect !== null && t.effect instanceof OpaqueBehavior) {
			return (t.effect as OpaqueBehavior).bodies.head
		}
		return ''''''
	}

	def static getGuard(Transition t) {
		if (t.guard !== null && t.guard.specification instanceof OpaqueExpression) {
			val opaqueExpression = t.guard.specification as OpaqueExpression;
			if (opaqueExpression.languages.size === opaqueExpression.bodies.size) {
				for (var i = 0; i < opaqueExpression.languages.size; i++) {
					val language = opaqueExpression.languages.get(i)
					val matcher = CCodeGenConstants.supportedLanguages.matcher(language);
					if (matcher.matches()) {
						return GenUtils.cleanCR(opaqueExpression.bodies.get(i));
					}
				}
			}
		}
		return ""
	}
	
	def static getGuard(Transition t, Pattern selectedLanguages) {
		if (t.guard !== null && t.guard.specification instanceof OpaqueExpression) {
			val opaqueExpression = t.guard.specification as OpaqueExpression;
			if (opaqueExpression.languages.size === opaqueExpression.bodies.size) {
				for (var i = 0; i < opaqueExpression.languages.size; i++) {
					val language = opaqueExpression.languages.get(i)
					val matcher = selectedLanguages.matcher(language);
					if (matcher.matches()) {
						return GenUtils.cleanCR(opaqueExpression.bodies.get(i));
					}
				}
			}
		}
		return ""
	}
}
