import clr
import sys

clr.AddReference("GenTool_CsDataServerDomAsr4.dll")
from GenTool_CsDataServerDomAsr4.Iface import ReferrableType

class ecucUtil:

	def __init__(self):
		self.logfile = 0

# Pass an opened file to get a csv log of the created EcuC values. Pass 0 if no log required.
	def initLogFile(self, logfile):
		self.logfile = logfile
		self.logfile.write('Module	Module	Container	Parameter/Reference	Value	Reference to Definition\n')

	def addDefinition(self, obj, destType, definition):
		obj.DefinitionSpecified = True
		obj.Definition.DestType = destType
		obj.Definition.Value = definition

	def isOfDefinition(self, ecucValueObj, defRef):
		if ecucValueObj.DefinitionSpecified == True:
			if ecucValueObj.Definition.Value == defRef.AsrPath:
				return True
		return False

	def addValue(self, obj, value):
		obj.ValueSpecified = True
		if type(obj.Value) is str:
			obj.Value = str(value)
		else:
			# Numerical values/non-string values have a container that stores the actual value
			obj.Value.Value = str(value)

	def createAnnotation(self, obj, origin, text):
		anno = obj.AddNewAnnotation()
		anno.LabelSpecified = True
		anno.AnnotationOriginSpecified = True
		anno.AnnotationOrigin = origin
		anno.AnnotationTextSpecified = True
		label = anno.Label
		l4 = label.AddNewL4()
		l4.Value = text
		return anno


	def populateParamValue(self, param, destType, definition, value):
		self.addDefinition(param, destType, definition)
		self.addValue(param, value)

	def createNumericalParamValue(self, container, defRef, value):
		param = container.AddNewParameterValueAsEcucNumericalParamValue()
		self.populateParamValue(param, defRef.IdType, defRef.AsrPath, value)
		if self.logfile != 0:
			self.logfile.write('			EcucNumericalParamValue	{}	{}\n'.format(value, defRef.AsrPath))
		return param

	def createTextualParamValue(self, container, defRef, value):
		param = container.AddNewParameterValueAsEcucTextualParamValue()
		self.populateParamValue(param, defRef.IdType, defRef.AsrPath, value)
		if self.logfile != 0:
			self.logfile.write('			EcucTextualParamValue	{}	{}\n'.format(value, defRef.AsrPath))
		return param

	def createRefValue(self, container, defRef, asrPath):
		ref = container.AddNewReferenceValueAsEcucReferenceValue()
		self.addDefinition(ref, defRef.IdType, defRef.AsrPath)
		ref.ValueSpecified = True
		ref.Value.DestType = ReferrableType.tEcucContainerValue
		ref.Value.Value = asrPath
		if self.logfile != 0:
			self.logfile.write('			EcucReferenceValue	{}	{}\n'.format(asrPath, defRef.AsrPath))
		return ref

	def createContainer(self, module, shortName, defRef):
		container = module.AddNewContainer()
		container.ShortName = shortName
		self.addDefinition(container, defRef.IdType, defRef.AsrPath)
		if self.logfile != 0:
			self.logfile.write('		{}			{}\n'.format(container.AsrPath, defRef.AsrPath))
		return container

	def createSubContainer(self, container, shortName, defRef):
		subContainer = container.AddNewSubContainer()
		subContainer.ShortName = shortName
		self.addDefinition(subContainer, defRef.IdType, defRef.AsrPath)
		if self.logfile != 0:
			self.logfile.write('		{}			{}\n'.format(subContainer.AsrPath, defRef.AsrPath))
		return subContainer

	def createVariationPoint(self, container, pbVariantId):
		container.VariationPointSpecified = True
		pbCondition = container.VariationPoint.AddNewPostBuildVariantCondition()
		pbCondition.MatchingCriterionSpecified = True
		pbCondition.MatchingCriterion.DestType = ReferrableType.tPostBuildVariantCriterion
		pbCondition.MatchingCriterion.Value = '/VariantDefinition/Criterion/ECU'
		pbCondition.ValueSpecified = True
		pbCondition.Value.Value = str(pbVariantId)
		return pbCondition

	def createModule(self, package, shortName, defRef, valueCollection):
		module = package.AddNewElementAsEcucModuleConfigurationValues()
		module.ShortName = shortName
		module.DefinitionSpecified = True
		module.Definition.DestType = ReferrableType.tEcucModuleDef
		module.Definition.Value = defRef.AsrPath
		if self.logfile != 0:
			self.logfile.write('	{}				{}\n'.format(module.AsrPath, defRef.AsrPath))
		return module

	def addModuleToEcucValueCollection(self, module, valueCollection):
		newEcucModuleConfigurationValuesRefConditional = valueCollection.AddNewEcucValue()
		newEcucModuleConfigurationValuesRefConditional.EcucModuleConfigurationValuesSpecified = True
		newEcucModuleConfigurationValuesRefConditional.EcucModuleConfigurationValues.Value = module.AsrPath
		newEcucModuleConfigurationValuesRefConditional.EcucModuleConfigurationValues.DestType = module.IdType

	def addMissingModulesToEcucValueCollection(self, package, ecucValueCollection):
		ecucValuesToAdd = []
		for element in package.ElementList:
			if element.IdType == ReferrableType.tEcucModuleConfigurationValues:
				found = False
				for v in ecucValueCollection.EcucValueList:
					if v.EcucModuleConfigurationValues.Value == element.AsrPath:
						found = True
						break
				if not found:
					ecucValuesToAdd.append(element)
		for el in ecucValuesToAdd:
			self.addModuleToEcucValueCollection(el, ecucValueCollection)