/*****************************************************************************
 * Copyright (c) 2013, 2016 CEA LIST.
 *
 * 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:
 *  Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
 *****************************************************************************/
import org.eclipse.papyrus.interoperability.common.utils.UI;
import org.eclipse.papyrus.interoperability.common.utils.NotationTypes;
import libraries.EclipseUI;
import org.eclipse.papyrus.interoperability.rsa.RTMappings; 
import org.eclipse.papyrus.interoperability.common.blackboxes.emf.EMFResource;

modeltype notation "strict" uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation';
modeltype umlNotation "strict" uses 'http://www.eclipse.org/papyrus/umlnotation';
modeltype uml "strict" uses 'http://www.eclipse.org/uml2/5.0.0/UML';
modeltype ecore "strict" uses 'http://www.eclipse.org/emf/2002/Ecore';
modeltype sash "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/sashdi';
modeltype config "strict" uses 'http:///RSAToPapyrusParameters.ecore';

/**
*	Transformation rules for importing an RSA Semantic model into Papyrus (SashModel + cleanup semantics)
*/
transformation RSAModelToPapyrus(inout semantics : uml, inout graphics : notation, out di : sash, in param : config);


main() {
	assert fatal (not semantics.rootObjects()[uml::Element]->isEmpty()) with log('Cannot find root uml::Element');
	
	//semantics.objectsOfType(Element).map deleteSourceDiagrams(); //TODO programatically to clean up everything (Avoid memory leaks)
	
	if param.rootObjects()[Config]->any(true).convertOpaqueExpressionToLiteralString then
		semantics.objectsOfType(OpaqueExpression).map convertToLiteralString()
	endif;
	
	semantics.objectsOfType(OpaqueExpression).map fixLanguage();
	semantics.objectsOfType(Stereotype).map fixBaseProperties(); //Bug 492872: Multiplicity change between UML 2.3 (RSA) and 2.4+ (Papyrus)
}

//If the OpaqueExpression doesn't have a language, and a single body, replace it with a LiteralString
mapping inout OpaqueExpression::convertToLiteralString() : LiteralString when {
	(self.language->size() = 0 and self.body->size() <= 1) or
	(self.language->size() = 1 and self.body->size() <= 1 and 
		self.language->at(1).isEmpty()
	)
} {
	init {
		result := self.map toLiteralString() //Blackbox cast: Transform OpaqueExpression to LiteralString (Preserve incoming references and compatible features)
	}

	result.value := if self.body->size() = 0 then null else self.body->at(1) endif;	
	
	self.oclAsType(EObject).forceDelete(true); //Destroy the source OpaqueExpression
	worked(1);
}

intermediate class Opaque { 
	language: String; 
	body: String;
}
	
mapping inout OpaqueExpression::fixLanguage() when {
	(self.language->size() > 1 or self.body->size() > 1) and 
	(self.language->exists(isEmpty()) or self.language.size() <> self.body.size())
} {
	//Replace empty languages by "Undefined" (In Papyrus, "Empty" is interpreted as "OCL", which is the default. This is not the case in RSA, where "Empty" means "Undefined")

	var maxSize : Integer := self.language->size().max(self.body->size());

	var newLanguages : OrderedSet(Opaque) := OrderedSet{};
	var i : Integer = 1;
	
	while(i <= maxSize) {
		var lang : String := self.language->at(i);
		var body : String := self.body->at(i);
		
		var newLanguage := object Opaque{};
		newLanguage.language := if lang.oclIsInvalid() or lang.isEmpty() then 'Undefined' else lang endif;
		newLanguage.body := if body.oclIsInvalid() or body.isEmpty() then '' else body endif;
		
		newLanguages += newLanguage;
		
		i := i+1;
	};
	
	self.language := newLanguages.language;
	self.body := newLanguages.body;	
}


//Bug 492872: Multiplicity change between UML 2.3 (RSA) and 2.4+ (Papyrus)
mapping inout Stereotype::fixBaseProperties() when {
	self.baseProperties()->size() > 1
}{
	self.baseProperties().map fixMultiplicity();
}

mapping inout Property::fixMultiplicity() {
	if (not self.lowerValue.oclIsUndefined()) and self.lowerValue.oclIsKindOf(LiteralInteger) then
		self.lowerValue.oclAsType(LiteralInteger).value := 0
	else
		self.lowerValue := object LiteralInteger {
			value := 0;
		}
	endif;
	
	if (not self.upperValue.oclIsUndefined()) and self.upperValue.oclIsKindOf(LiteralUnlimitedNatural) then
		self.upperValue.oclAsType(LiteralUnlimitedNatural).value := 1
	elif (not self.upperValue.oclIsUndefined()) and self.upperValue.oclIsKindOf(LiteralInteger) then
		self.upperValue.oclAsType(LiteralInteger).value := 1
	else
		self.upperValue := object LiteralUnlimitedNatural {
			value := 1;
		}
	endif;
}

query String::isEmpty() : Boolean {
	return self.oclIsUndefined() or self = '';
}

query Stereotype::baseProperties() : Set(Property){
	return self.ownedAttribute->select(p | p.name.startsWith("base_") and p.type.oclIsTypeOf(Class)) //Typed with a UML Metaclass
}

