-*
	This transformation runs very slowly for the large model, which contains
	a much larger number of IdentifierReferences (198141) than Classes (4586).
    In particular, only 11 of the 4586 classes are to be transformated to states,
    and hence many of the identifier references are contained in classes that
    are not states, and do not need to be transformed.

	Using the @lazy annotation on the IdentifierReference2Transition does
    not seem to improve performance, possibly because DefaultTransformationStrategy
    is used instead of FastTransformationStrategy when an ETL transformation
    has any rules that use the @lazy annotation.
*-

pre {
	var machine = new StateMachine!StateMachine;
	
	Class.all.size.println("Classes: ");
	IdentifierReference.all.size.println("IdentifierReferences: ");
}

rule Class2State 
	transform c : Java!Class
	to s : StateMachine!State {
	
	guard: c.isState()
	
	s.name = c.name;
	machine.states.add(s);
	
	s.out = c.members.select(m : Method | true).collect(m|m.eAllContents.select(e:IdentifierReference|true)).flatten().equivalent();
}

rule IdentifierReference2Transition
	transform ir : Java!IdentifierReference
	to t : StateMachine!Transition {

	guard: ir.isTransition()

	t.src = ir.getClass().equivalent();
	t.dst = ir.getTargetClass().equivalent();
	
	t.trigger = ir.getTrigger();
	t.action  = ir.getAction();
				
	machine.transitions.add(t);
}

@cached
operation IdentifierReference isTransition() : Boolean {
	return self.getClass().isState() and 
	       self.next.isDefined() and self.next.target.name == "Instance" and
	       self.next.next.isDefined() and self.next.next.target.name == "activate";
}

@cached
operation IdentifierReference getClass() : Class {
	var class = self;
	
	while (not class.isKindOf(Class)) {
		class = class.eContainer();
	}
	
	return class;
}

@cached
operation IdentifierReference getTargetClass() : Class {
	return Java!Class.all.selectOne(c|c.name == self.target.name);
}

@cached
operation IdentifierReference getTrigger() : String {
	if (self.getContainingMethod().name <> "run") {
		return self.getContainingMethod().name;
	
	} else if (self.getContainingStatementListContainer().isKindOf(NormalSwitchCase)) {
		return self.getContainingStatementListContainer().condition.target.name;
	
	} else if (self.getContainingStatementListContainer().isKindOf(CatchBlock)) {
		return self.getContainingStatementListContainer().parameter.typeReference.classifierReferences.first.target.name;
	
	} else {
		return "--";
	}
}

@cached
operation IdentifierReference getContainingMethod() : String {
	var method = self;
	
	while (not method.isKindOf(Method)) {
		method = method.eContainer();
	}
	
	return method;
}

@cached
operation IdentifierReference getAction() : String {
	var send = self.getContainingStatementListContainer().getSendMethod();
	
	if (send.isDefined()) {
		return send.arguments.first.next.target.name;
	} else {
		return "--";
	}
}

@cached
operation IdentifierReference getContainingStatementListContainer() : StatementListContainer {
	return self.eContainer().eContainer();
}

@cached
operation StatementListContainer getSendMethod() : MethodCall {
	var statementContainingSendMethod = self.statements.selectOne(s:ExpressionStatement|s.expression.isKindOf(MethodCall));
	
	if (statementContainingSendMethod.isDefined()) {
		return statementContainingSendMethod.expression;
	}
}

@cached
operation Class isState() : Boolean {
	return self.isConcrete() and self.anySuperTypesIsState();
}

@cached
operation Class isConcrete() : Boolean {
	return not self.annotationsAndModifiers.exists(m|m.isKindOf(Abstract));
}

@cached
operation Class anySuperTypesIsState() : Boolean {
	if (self.getSuperType().isDefined()) {
		if (self.getSuperType().name == "State") {
			return true;
		} else {
			return self.getSuperType().anySuperTypesIsState();
		}
	}
	
	return false;
}

@cached
operation Class getSuperType() : Class {
	var supertype : Class = null;
	
	if (self.`extends`.isDefined() and self.`extends`.getClassifier() <> self) {
		supertype = self.`extends`.getClassifier();
	}
	
	return supertype;
}

@cached
operation NamespaceClassifierReference getClassifier() {
	return self.classifierReferences.first.getClassifier();
}

@cached
operation ClassifierReference getClassifier() {
	var classifier = null;
	
	// some classes aren't contained in this model, e.g. Throwable
	if (self.target.isDefined() and Java.owns(self.target)) {
		classifier = self.target;
	}
	
	return classifier;
}