/*
 * This file specifies a QVTo transformation.
 */
 
 /*
 * Copyright (c) 2022 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:
 *    Florian Pauker (TU Wien) pauker@ift.at
 *    Thomas Fruhwirth (TU Wien) thomas.fruehwirth@tuwien.ac.at
 *    Saadia Dhouib (CEA LIST) saadia.dhouib@cea.fr
 *    Fadwa Tmar (CEA LIST) fadwa.tmar@cea.fr 
 *******************************************************************************/
 
import Common.Helpers;
import ClassDiagram.Classes;
import StateMachineDiagram.StateMachines;

modeltype UML uses 'http://www.eclipse.org/uml2/5.0.0/UML';
modeltype SYSML uses 'http://www.eclipse.org/papyrus/sysml/1.6/SysML';
modeltype BLOCKS uses 'http://www.eclipse.org/papyrus/sysml/1.6/SysML/Blocks';
modeltype OPCUA uses set('http://opcfoundation.org/UA/2011/03/UANodeSet.xsd');
modeltype TYPES uses types('http://opcfoundation.org/UA/2008/02/Types.xsd');
modeltype ecore uses 'http://www.eclipse.org/emf/2002/Ecore';
modeltype NodeIdsCsv uses NodeIdsCsv('http://org.eclipse.papyrus.opcua.uml2opcua.nodeIdsCsv.ecore');


modeltype OPCUA_Robotics_Profile uses 'http://Papyrus/OPCUARoboticsProfile';





modeltype OPCUA_Robotics uses opcuarobotics('http://opcfoundation.org/UA/Robotics/');
/*
 * UML to OPC UA Model Transformation using QVTo 
 * @param umlInputModel The UML input model.
 * @param opcuaOutputModel The OPC UA output model that will be generated from the umlInputModel by means of model transformation.
 */
//transformation UMLtoOPCUA(in umlInputModel : UML, out opcuaOutputModel : OPCUA, out nodeIdsCsvOutputModel : NodeIdsCsv, in sysml : SYSML, in robotics:OPCUA_Robotics_Profile, in diProfile:OPCUA_DI_Profile, in uaProfile : OPCUA_Profile );
transformation UMLtoOPCUA(in umlInputModel : UML, in roboticsProfile:UML, out opcuaOutputModel : OPCUA, out nodeIdsCsvOutputModel : NodeIdsCsv);



property roboticsProfileProfile : UML::Profile = roboticsProfile.rootObjects()![UML::Profile];
property testMotionDeviceSystemTypeStereotype : UML::Stereotype =roboticsProfileProfile.ownedStereotype![name = "MotionDeviceSystemType"];

/*
 * The main entry point of the transformation.
 */
main() {
	log("Starting UML 2 OPC UA transformation using QVTo");
	
	// initilize internal datastructures
	addNamespace(0, OPCUA_NAMESPACE_URI); // this Namespace Uri always needs to be added
	// Namespace Uri DI and Robotics are added only if the robotics profile is applied 
	if(roboticsProfileProfile!=null) {
		addNamespace(1, OPCUA_DI_NAMESPACE_URI); 
		addNamespace(2, OPCUA_ROBOTICS_NAMESPACE_URI);
	} ;
	// the transformation supports the use of NodeId aliases, i.e. using human-readable names instead of NodeIds
	// these aliases can either be read from a NodeId CSV file, or aliases internally defined in Helpers.qvto 
	if(CFG_USE_BLACKBOX) {
		loadExternalNodeIds(OPCUA_NAMESPACE_URI, "/NodeIds/NS0/NodeIds.csv");
	} else {
		loadInternalNodeIds();
	};

	// create a OPCUA::DocumentRoot as the top-level element of the OPC UA model
	var documentRoot := object OPCUA::DocumentRoot{};
	
	// map UML::Model elements to OPCUA::NodeSetType elements and collect them in a set
	// TODO: verify what happens if the inputModel contains multiple UML::Model elements
	var x := documentRoot.xMLNSPrefixMap;
	documentRoot.uANodeSet += umlInputModel.rootObjects()->selectByType(UML::Model)->map model2OPCUANodeSetType();
	
}

/*
 * Transformation rule mapping a UML::Model element to an OPCUA::UANodeSetType element
 */
mapping UML::Model::model2OPCUANodeSetType() : OPCUA::UANodeSetType {
	log("model2OPCUANodeSetType for UML element " + self.name);
	
	// process all UML::Packages
	
	self.ownedElement->selectByType(UML::Package).package2Namespace(result);
	
	// map UML::Classes with stéréotypes : if there is a stereotype that's mean that 
	//the type is allaready defined in on of the extentions of OPC UA (exple DI or Robitcs)
	
	
	uAObject += self.ownedElement->selectByType(UML::Class)->select(c|c.getAppliedStereotypes()->exists(s|s.name='MotionDeviceSystemType'))-> map class2MotionDeviceSystemObject(result);
	uAObject += self.ownedElement->selectByType(UML::Class)->select(c|c.name.equalsIgnoreCase("RobotSystem")) -> map class2MotionDeviceSystemObject(result);

	// map UML::Classes without stéréotypes
	// map UML::Classes to OPCUA::UAObjectTypes that are not included in any namspeace
	uAObjectType += self.ownedElement->selectByType(UML::Class)->map class2OPCUAObjectType(result);

	// map UML::InstanceSpecification to OPCUA::UAObject that are not included in any namspeace
	uAObject += self.ownedElement->selectByType(UML::InstanceSpecification)->map instanceSpecification2OPCUAObject(result);

	// map UML::StateMachines to OPCUA::UAObjectTypes that are not included in any namspeace
	uAObjectType += self.ownedElement->selectByType(UML::StateMachine)->map statemachine2FiniteStateMachineType(result);
	
	// although UML::Associations are top-level elements in a model, UML::Association to OPCUA::Reference transformation is handled as part of the class transformation

	// create a OPCUA::UriTable and link it to the DocumentRoot
	namespaceUris := object OPCUA::UriTable{};
	fillUriTable(namespaceUris);
	
	//TODO add URI for each applied profile
	models :=object OPCUA ::ModelTable{};
	//TODO add model element of type ModelTableEntry for each profile 
	//models 
	
	// create an OPCUA::Alias table
	if(CFG_ENABLE_ALIAS_TABLE) {
		aliases := object OPCUA::AliasTable{};
		fillAliasTable(aliases);
	};
	
	// create NodeIdCsv
	var nodeIdsCsvFile := object NodeIdsCsv::NodeIdsCsvFile{};
	result.createNodeIdsCsv(nodeIdsCsvFile);
}

helper UML::Package::package2Namespace(inout nodeset : OPCUA::UANodeSetType) {
	// map all UML::Class in this package to OPCUA::UAObjectTypes and collect them in a set
	nodeset.uAObjectType += self.ownedElement->selectByType(UML::Class)->map class2OPCUAObjectType(nodeset);

	// map all UML::InstanceSpecification in this package to OPCUA::UAObject and collect them in a set
	nodeset.uAObject += self.ownedElement->selectByType(UML::InstanceSpecification)->map instanceSpecification2OPCUAObject(nodeset);

	// map all UML::StateMachine in this package to OPCUA::FinitStateMachineType and collect them in a set
	nodeset.uAObjectType += self.ownedElement->selectByType(UML::StateMachine)->map statemachine2FiniteStateMachineType(nodeset);
}





