/*
-----------------------------------------------------------------------
--            CHESS ceiling assignment transformation                --
--                                                                   --
--                    Copyright (C) 2011-2012                        --
--                 University of Padova, ITALY                       --
--                                                                   --
-- Authors: Marco Panunzio         panunzio@math.unipd.it            --
--          Alessandro Zovi        azovi@math.unipd.it               --
--                                                                   --
-- 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-v20.html                         --
-----------------------------------------------------------------------
*/

import ProfileUtils_Inst_full;
import UMLUtils_Inst_full;
import chess.lib;
	
modeltype UML uses "http://www.eclipse.org/uml2/2.0.0/UML";
modeltype MARTEP uses "http://www.eclipse.org/papyrus/MARTE/1";
modeltype CHESS uses "http://CHESS";	
modeltype ECORE uses "http://www.eclipse.org/emf/2002/Ecore";
	
transformation CHESS_Assignment(inout source:UML);

property model : Model = null;
property MARTEProfile : Profile = null;
property CHESSProfile : Profile = null;

property assigns : Set(Comment) = null;

property compView : Package = null;
property deplView : Package = null;

property instSpecPackage : Package = null;
property instSpecPackageDepl : Package = null;

	
main() {
    log("*** CHESS Ceiling assignment transformation   ***");	
	model := source.rootObjects()![Model];
	
	MARTEProfile := model.getView("ComponentView").getAppliedProfiles()->selectOne(name="GCM").owner.owner.oclAsType(Profile);
	CHESSProfile := model.getAppliedProfiles()->selectOne(name="CHESS").oclAsType(Profile);
	
	initUtils(MARTEProfile, CHESSProfile);
	
	compView := model.getView("ComponentView");
	instSpecPackage := compView.allOwnedElements()[Package]->selectOne(not getMetaclass("CHESS::Core::CHGaResourcePlatform").oclIsUndefined());
	
	
	deplView := model.getView("DeploymentView");
	instSpecPackageDepl := deplView.allOwnedElements()[Package]->selectOne(not getMetaclass("CHESS::Core::CHGaResourcePlatform").oclIsUndefined());
	assigns := deplView.allOwnedElements()[Comment]->select(isStereotyped(AssignQN));
		
	model.map ModelWithCeiling();
	log("*** End of CHESS Ceiling assignment transformation   ***");
}

helper Set(Slot)::printCeilings(){
	self->forEach(ps) {
		var specs : Sequence(chessmlprofile::RTComponentModel::CHRtSpecification) := (ps.getMetaclass(CHRtPortSlotQN).oclAsType(chessmlprofile::RTComponentModel::CHRtPortSlot)).cH_RtSpecification->asSequence();
	    specs->forEach(spec) {
	    	var x := ps.definingFeature.qualifiedName + " " + spec.context.qualifiedName;
	    	x := x + " "+ spec.ceiling;
	    	log(x);
	    }
	};
}

mapping inout Model::ModelWithCeiling() {
	init{	
		var chrtPortSlotList : Set(Slot) :=instSpecPackage.allOwnedElements()[Slot]->select(ps | ps.isStereotyped(CHRtPortSlotQN))->asSet();
	}

	// Initialization of own ceilings of cyclic and sporadic operations
	// Initialization of ceiling of protected operation
	// Initialization of ceiling of unprotected operation
	chrtPortSlotList->forEach(ps) {
		var specs : Sequence(chessmlprofile::RTComponentModel::CHRtSpecification) := (ps.getMetaclass(CHRtPortSlotQN).oclAsType(chessmlprofile::RTComponentModel::CHRtPortSlot)).cH_RtSpecification->asSequence();
	    specs->forEach(spec) {
	    	if (spec.isDeferred()) then {
	    	   spec.ceiling := spec.relativePriority
	    	} else {
	   			spec.ceiling := "-127";
	    	} endif;
	    }
	};
	
	log("Before:");
	chrtPortSlotList->printCeilings();
	
	// Ceiling propagation
	chrtPortSlotList->forEach(ps) {
		var specs : Sequence(chessmlprofile::RTComponentModel::CHRtSpecification) := (ps.getMetaclass(CHRtPortSlotQN).oclAsType(chessmlprofile::RTComponentModel::CHRtPortSlot)).cH_RtSpecification->asSequence();
	    specs->forEach(spec) {
	    	if (spec.isDeferred()) then {
				ps.map propagateCeiling(spec);
	    	} endif
	    }
	};
	
	log("After:");
	chrtPortSlotList->printCeilings();
	
	
	//After ceiling propagation, remove ceilings of unprotected operations
	chrtPortSlotList->forEach(ps) {
		var specs : Sequence(chessmlprofile::RTComponentModel::CHRtSpecification) := (ps.getMetaclass(CHRtPortSlotQN).oclAsType(chessmlprofile::RTComponentModel::CHRtPortSlot)).cH_RtSpecification->asSequence();
	    specs->forEach(spec) {
	    	if ((not spec.isDeferred()) and (not spec.isProtected())) then {
				spec.ceiling := null;
	    	} endif
	    }
	}

}

mapping inout Slot::propagateCeiling(spec : chessmlprofile::RTComponentModel::CHRtSpecification) {
   init {
   		var ceilingToPropagate := spec.ceiling;
   		var sourceOp : Operation := spec.context.oclAsType(Operation);
   		var currInstance : InstanceSpecification := self.owningInstance; 
   }
      
   if (sourceOp.method->notEmpty()) then {
   		var act := (sourceOp.method->asSequence()->first().oclAsType(Activity));
   		var coaList := act.collectCallOperationNodes();   		
   		
   		coaList->forEach(coa) {
			var calledOp := coa.operation;
			var riPort := coa.onPort;
			var riSlot : Slot := currInstance.slot[definingFeature = riPort]->any(true);
			var connectedSlot : Slot := riSlot.getConnectedSlot(currInstance);
			var CHRtSpec := connectedSlot.CHRtSpecForOperation(calledOp);
			
			/* If the component instances are deployed on different nodes
			*  we need to set the ceiling priority to the priority of the
			*  server task of the middleware.
			*  Currently it is hardcoded to 27.
			*/
			
			if (not riSlot.owningInstance.isDeployedOnSameProcesor(connectedSlot.owningInstance)) then
			   ceilingToPropagate := "27"
			endif;
			
			
			if (ceilingToPropagate.asInteger() > CHRtSpec.ceiling.asInteger()) then {
				if (CHRtSpec.isDeferred()) then {
				   //Raise the ceiling of the OBCS and terminate
				   CHRtSpec.ceiling := ceilingToPropagate;
				   		
				} else { 
					if (CHRtSpec.isProtected()) then {
				   		//Raise the ceiling of the protected object 
				   		// (i.e. all protected operations of the slot) 
				   		// and recursively continue
				   		CHRtSpec.ceiling := ceilingToPropagate;
				   		connectedSlot.map propagateCeiling(CHRtSpec);
				   		
				   		var specs : Sequence(chessmlprofile::RTComponentModel::CHRtSpecification) := 
				   		   (connectedSlot.getMetaclass(CHRtPortSlotQN).oclAsType(chessmlprofile::RTComponentModel::CHRtPortSlot)).cH_RtSpecification->asSequence();
	   						specs ->forEach(mySpec) {

				   			if (mySpec.isProtected()) then {							
								if (ceilingToPropagate.asInteger() > mySpec.ceiling.asInteger()) then {
								    mySpec.ceiling := ceilingToPropagate;
									connectedSlot.map propagateCeiling(mySpec);
								} endif;								
				   			} endif;
				   		}
				   	} else {//Unprotected
				   		CHRtSpec.ceiling := ceilingToPropagate;
				   		connectedSlot.map propagateCeiling(CHRtSpec);
				   	} endif;
				} endif;
			} endif;					
   		};
   } endif;
   
}

query InstanceSpecification::isConnectorInstance() : Boolean {
	if (self.classifier->isEmpty()) then
		if (self.slot->any(true).isStereotyped(ClientServerPortQN)) then
			return true
		endif
	endif;
	return false;
}

query Element::isNullOrInvalid() : Boolean {
	if(self.oclIsInvalid() or self.oclIsUndefined())then
		return true
	endif;
	return self.isNull();
}

query Slot::getConnectedSlot(compInst : InstanceSpecification) : Slot {
	var riPort := self.definingFeature.oclAsType(Port);
	var myInstanceValue : InstanceValue := null;
	var connectorPIslot : Slot := null;
	var targetInstance : InstanceSpecification := null;

	var connectorInstList := InstanceSpecification.allInstances()->select(classifier->size() = 0);
	connectorInstList->forEach(connInst) {
	    var candidateSlot : Slot := connInst.slot->selectOne(definingFeature = riPort);
	    if (candidateSlot.oclIsInvalid()) continue endif;
	    if (not candidateSlot.isNullOrInvalid()) then {
	       myInstanceValue := (candidateSlot.allOwnedElements()[InstanceValue])->selectOne(instance = compInst);
	       if (myInstanceValue.oclIsInvalid()) continue endif;
	       if (not myInstanceValue.isNullOrInvalid()) then {
	          connectorPIslot := connInst.slot->selectOne(definingFeature <> riPort);
	          targetInstance := connectorPIslot.value->selectOne(true).oclAsType(InstanceValue).instance;
	          return targetInstance.slot->selectOne(definingFeature = connectorPIslot.definingFeature);
	       } endif;
	    } endif;
		
	};
	return null;
}

query InstanceSpecification::isDeployedOnSameProcesor(is : InstanceSpecification) : Boolean {
	var proc1 : InstanceSpecification := getDeploymentProcessor(self);
	return proc1 = getDeploymentProcessor(is);
}


query getDeploymentProcessor(p : InstanceSpecification) : InstanceSpecification {
	var a := assigns -> selectOne(isAssignedFrom(p));
	var asg := a.getMetaclass(AssignQN).oclAsType(MARTE::MARTE_Foundations::Alloc::Assign);
	return 	asg.to![InstanceSpecification];
}

/**
 * Start of reused code by azovi
 */

/*
  Given an ICB-Activity return the list of all its CallOperationAction nodes,
  assuming that their are all connected in a single chain: no loops and branches.
  
  older version. current one has been moved in UMLUtils_Inst_full.qvto
*/
query Activity::collectCallOperationNodesOLD() : Sequence(CallOperationAction) {
	var nodes : Sequence(CallOperationAction) := Sequence{};
	var prevNode : ActivityNode := self.node![InitialNode];
	var nextNode : ActivityNode;
	while(true){
		nextNode := prevNode.outgoing->any(true).target.oclAsType(CallOperationAction);
		if (nextNode.oclIsInvalid()) break endif;
		if (not nextNode.isNullOrInvalid()) then {
			nodes += nextNode.oclAsType(CallOperationAction);
			prevNode := nextNode;
		}
		else{
			break;
		}
		endif;
	};
	return nodes;
}

query chessmlprofile::RTComponentModel::CHRtSpecification::isDeferred() : Boolean {
	var arrivalPattern := self.occKind.getArrivalPatternType();
	//the operation is deferred if the arrival pattern is: periodic, sporadic, bursty
	if  arrivalPattern.oclIsInvalid() then
		return false
	endif;
	return (arrivalPattern <> null and arrivalPattern.length() <> 0);
}

query chessmlprofile::RTComponentModel::CHRtSpecification::isSporadic() : Boolean {
	var arrivalPattern := self.occKind.getArrivalPatternType();
	return (arrivalPattern.equalsIgnoreCase("sporadic"));// and self.isGuarded());
}

query chessmlprofile::RTComponentModel::CHRtSpecification::isProtected() : Boolean { 
	return (not self.isDeferred()) and self.protection = MARTE::MARTE_DesignModel::HLAM::CallConcurrencyKind::guarded;
}

query Port::getConnectedPort() : Port {
	var bindingConnector := self.getConnector();
	var myConnectorEnd := (bindingConnector.allOwnedElements()[ConnectorEnd])->	selectOne(role <> self);
    return myConnectorEnd.role.oclAsType(Port);
}


query Comment::isAssignedFrom(p : InstanceSpecification) : Boolean {
    var asg := self.getMetaclass(AssignQN).oclAsType(MARTE::MARTE_Foundations::Alloc::Assign);
    return asg._from![InstanceSpecification] = p;
}
