/**
 * Copyright (c) 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.slg.linux.transformers.sw;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.app4mc.amalthea.model.ActivityGraphItem;
import org.eclipse.app4mc.amalthea.model.Amalthea;
import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
import org.eclipse.app4mc.amalthea.model.Group;
import org.eclipse.app4mc.amalthea.model.InterProcessStimulus;
import org.eclipse.app4mc.amalthea.model.InterProcessTrigger;
import org.eclipse.app4mc.amalthea.model.Process;
import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
import org.eclipse.app4mc.amalthea.model.ProcessingUnitDefinition;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.RunnableCall;
import org.eclipse.app4mc.amalthea.model.Task;
import org.eclipse.app4mc.amalthea.model.util.DeploymentUtil;
import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
import org.eclipse.app4mc.slg.linux.generators.LinuxTaskGenerator;
import org.eclipse.app4mc.slg.linux.transformers.LinuxBaseTransformer;

import com.google.inject.Singleton;

@Singleton
public class LinuxTaskTransformer extends LinuxBaseTransformer {

	// ---------- generic part "def create new transform(...)" ----------

	private final Map<List<Object>, SLGTranslationUnit> transformCache = new HashMap<>();

	public Map<List<Object>, SLGTranslationUnit> getCache() {
		return this.transformCache;
	}

	public SLGTranslationUnit transform(final Task task) {
		final List<Object> key = new ArrayList<>(Arrays.asList(task));
		final SLGTranslationUnit tu;

		synchronized (transformCache) {
			if (transformCache.containsKey(key)) {
				return transformCache.get(key);
			}
			tu = createTranslationUnit(task);
			transformCache.put(key, tu);
		}

		// if translation unit is newly created and valid -> create files
		if (tu.isValid()) {
			doTransform(tu, task);
		}

		return tu;
	}

	// ---------------------------------------------------

	private SLGTranslationUnit createTranslationUnit(final Task task) {
		if ((task == null)) {
			return new SLGTranslationUnit("UNSPECIFIED TASK");
		} else {
			String basePath = "synthetic_gen";
			String moduleName = "tasks";
			String call = task.getName() + "()";
			return new SLGTranslationUnit(basePath, moduleName, call);
		}
	}

	private void doTransform(final SLGTranslationUnit tu, final Task task) {
		genFiles(tu, task);
	}

	private void genFiles(SLGTranslationUnit tu, final Task task) {
		final Amalthea root = AmaltheaServices.getContainerOfType(task, Amalthea.class);
		final Set<ProcessingUnit> assignedCores = DeploymentUtil.getAssignedCoreForProcess(task, root);

		final StringBuilder puDefinition = new StringBuilder("default");

		if (assignedCores != null && !assignedCores.isEmpty()) {
			puDefinition.delete(0, puDefinition.length());

			ProcessingUnit pu = assignedCores.iterator().next();
			ProcessingUnitDefinition puDef = pu.getDefinition();
			String puDefName = (puDef == null) ? null : puDef.getName();

			puDefinition.append(puDefName);
		}

		final List<String> statements = new ArrayList<>();
		final List<Process> processedTasks = new ArrayList<>();

		if (task != null && task.getActivityGraph() != null) {
			for (ActivityGraphItem item : task.getActivityGraph().getItems()) {

				if (item instanceof Group) {
					for (ActivityGraphItem item2 : ((Group) item).getItems()) {
						if ((item2 instanceof RunnableCall)) {
							final Runnable runnable = ((RunnableCall) item2).getRunnable();
							statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
						} else if ((item2 instanceof InterProcessTrigger)) {
							InterProcessStimulus stimulus = ((InterProcessTrigger) item2).getStimulus();
							LinuxTaskGenerator.handleInterProcessTrigger(statements, processedTasks, stimulus);
						}
					}
				} else if (item instanceof RunnableCall) {
					final Runnable runnable = ((RunnableCall) item).getRunnable();
					if ((runnable != null)) {
						statements.add("run_" + runnable.getName() + "(\"" + puDefinition.toString() + "\");");
					}
				} else if (item instanceof InterProcessTrigger) {
					InterProcessStimulus stimulus = ((InterProcessTrigger) item).getStimulus();
					LinuxTaskGenerator.handleInterProcessTrigger(statements, processedTasks, stimulus);
				}
			}
		}

		if (isIncFileEmpty(tu)) {
			incAppend(tu, LinuxTaskGenerator.snippetIncStart());
		}
		if (isSrcFileEmpty(tu)) {
			srcAppend(tu, LinuxTaskGenerator.snippetSrcStart());
		}
		srcAppend(tu, LinuxTaskGenerator.toCpp(task, statements));
		incAppend(tu, LinuxTaskGenerator.toH(task));
	}

}
