/**
 ********************************************************************************
 * Copyright (c) 2019-2020 Robert Bosch GmbH.
 * 
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 * 
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     Robert Bosch GmbH - initial API and implementation
 ********************************************************************************
 */

package org.eclipse.app4mc.amlt2systemc.m2t.transformers.mapping

import com.google.inject.Inject
import com.google.inject.Singleton
import java.util.ArrayList
import org.eclipse.app4mc.amalthea.model.AbstractMemoryElement
import org.eclipse.app4mc.amalthea.model.Channel
import org.eclipse.app4mc.amalthea.model.Label
import org.eclipse.app4mc.amalthea.model.Memory
import org.eclipse.app4mc.amalthea.model.MemoryMapping
import org.eclipse.app4mc.amalthea.model.ModeLabel
import org.eclipse.app4mc.amlt2systemc.m2t.module.BaseTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.TranslationUnit
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.hw.MemoryTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.sw.ChannelTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.sw.LabelTransformer
import org.eclipse.app4mc.amlt2systemc.m2t.transformers.sw.ModeLabelTransformer
import org.eclipse.app4mc.transformation.util.OutputBuffer

@Singleton
class MemoryMappingTransformer extends BaseTransformer {

	@Inject OutputBuffer outputBuffer
	@Inject MemoryTransformer memoryTransformer
	@Inject LabelTransformer labelTransformer
	@Inject ChannelTransformer channelTransformer
	@Inject ModeLabelTransformer modeLabelTransformer

	static def String getModulePath() {
		return MappingModelTransformer.getModulePath() + "/memoryMapping"
	}

	def String getModuleName(AbstractMemoryElement element, Memory memory) {
		return getModulePath() + "/memoryMapping"//_" + element.name + "_to_" + memory.name
	}

	def String getCall(AbstractMemoryElement element, Memory memory) '''
	init_MemoryMapping_«element.name»_to_«memory.name»'''

	private def String getImplementation(String functionName, String memoryElementGetter, String memoryGetter,
		Long memoryAddress) '''
		void «functionName»(){
			MappingModel::addMemoryMapping(«memoryElementGetter», «memoryGetter»);
			MappingModel::addMemoryAddress(«memoryElementGetter», «memoryAddress»);
		}
	'''

	def TranslationUnit transform(MemoryMapping memoryMapping) {
		if (!memoryElementIsUsed(memoryMapping.abstractElement)){
			//only memory elements that are actually referred to somwhere in the 
			//sw model will be transformed, therefore mappings of unused labels 
			//must be skipped to avoid issues during compilation(during linking)
			return null;
		} else {
			return transformInternal(memoryMapping);
		}
	}
	
	private def create new TranslationUnit() transformInternal(MemoryMapping memoryMapping) {
		
		if (memoryMapping.abstractElement === null || memoryMapping.memory === null) {
			it.module = "/*incomplete memory mapping in input model*/"
			it.call = "/*incomplete memory mapping in input model*/"
			return;
		}
		it.module = getModuleName(memoryMapping.abstractElement, memoryMapping.memory)
		it.call = getCall(memoryMapping.abstractElement, memoryMapping.memory)
		toH(memoryMapping.abstractElement, memoryMapping.memory)
		toCpp(memoryMapping.abstractElement, memoryMapping.memory, memoryMapping.memoryPositionAddress)
	// includedMemories.add(memoryMapping.memory)
	}
	
	def dispatch memoryElementIsUsed(Channel element) {
		val ArrayList<?> _cacheKey = CollectionLiterals.newArrayList(element);
		return channelTransformer.cache.containsKey(_cacheKey);
	}
	def dispatch memoryElementIsUsed(Label element) {
		val ArrayList<?> _cacheKey = CollectionLiterals.newArrayList(element);
		return  labelTransformer.cache.containsKey(_cacheKey);
	}
	def dispatch memoryElementIsUsed(ModeLabel element) {
		val ArrayList<?> _cacheKey = CollectionLiterals.newArrayList(element);
		return modeLabelTransformer.cache.containsKey(_cacheKey)
	}
	def dispatch memoryElementIsUsed(AbstractMemoryElement element) {
		return false;
	}

//Label
	def dispatch void toH(Label label, Memory memory) {
		val moduleName = getModuleName(label, memory)
		if (!outputBuffer.bufferExists("INC", moduleName)) {
			outputBuffer.appendTo("INC", moduleName, "#include \"Common.h\"\n");
			outputBuffer.appendTo("INC", moduleName, "#include \"MappingModel.h\"\n");
		}
		outputBuffer.appendTo("INC", moduleName, "void " + getCall(label, memory) + "();\n");
	}

	def dispatch void toCpp(Label label, Memory memory, long address) {
		val moduleName = getModuleName(label, memory)
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + moduleName + ".h\"\n")
		val tuLabel = labelTransformer.transform(label)
		val tuMemory = memoryTransformer.transform(memory)
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + tuLabel.module + ".h\"\n");
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + tuMemory.module + ".h\"\n");
		outputBuffer.appendTo("SRC", 
			moduleName,
			getImplementation(getCall(label, memory), tuLabel.call, tuMemory.call + "()", address)
		)
	}

//Channel
	def dispatch void toH(Channel channel, Memory memory) {
		val moduleName = getModuleName(channel, memory)
		if (!outputBuffer.bufferExists("INC", moduleName)) {
			outputBuffer.appendTo("INC", moduleName, "#include \"Common.h\"\n");
			outputBuffer.appendTo("INC", moduleName, "#include \"MappingModel.h\"\n");
		}
		outputBuffer.appendTo("INC", moduleName, "void " + getCall(channel, memory) + "();\n");
	}

	def dispatch void toCpp(Channel channel, Memory memory, long address) {
		val moduleName = getModuleName(channel, memory)
		val tuChannel = channelTransformer.transform(channel)
		val tuMemory = memoryTransformer.transform(memory)
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + moduleName + ".h\"\n")
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + tuMemory.module + ".h\"\n");
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + tuChannel.module + ".h\"\n");
		outputBuffer.appendTo("SRC", 
			moduleName,
			getImplementation(getCall(channel, memory), tuChannel.call, tuMemory.call + "()", address)
		)
	}

//ModeLabel
	def dispatch void toH(ModeLabel modeModeLabel, Memory memory) {
		val moduleName = getModuleName(modeModeLabel, memory)
		if (!outputBuffer.bufferExists("INC", moduleName)) {
			outputBuffer.appendTo("INC", moduleName, "#include \"Common.h\"\n");
			outputBuffer.appendTo("INC", moduleName, "#include \"MappingModel.h\"\n");
		}
		outputBuffer.appendTo("INC", moduleName, "void " + getCall(modeModeLabel, memory) + "();\n");
	}

	def dispatch void toCpp(ModeLabel modeModeLabel, Memory memory, long address) {
		val moduleName = getModuleName(modeModeLabel, memory)
		val tuModeLabel = modeLabelTransformer.transform(modeModeLabel)
		val tuMemory = memoryTransformer.transform(memory)
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + moduleName + ".h\"\n")
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + tuMemory.module + ".h\"\n");
		outputBuffer.appendTo("SRC", moduleName, "#include \"../../../" + tuModeLabel.module + ".h\"\n");
		outputBuffer.appendTo("SRC", 
			moduleName,
			getImplementation(getCall(modeModeLabel, memory), tuModeLabel.call, tuMemory.call + "()", address)
		)
	}

	def getCache() { return this._createCache_transformInternal }

}
