/**
 * 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 org.eclipse.app4mc.amalthea.model.IDiscreteValueDeviation;
import org.eclipse.app4mc.slg.commons.m2t.CustomObjectsStore;
import org.eclipse.app4mc.slg.commons.m2t.transformers.SLGTranslationUnit;
import org.eclipse.app4mc.slg.config.ConfigModel;
import org.eclipse.app4mc.slg.linux.generators.LinuxTicksUtilsGenerator;
import org.eclipse.app4mc.slg.linux.transformers.LinuxBaseTransformer;

import com.google.inject.Inject;
import com.google.inject.Singleton;

@Singleton
public class LinuxTicksUtilsTransformer extends LinuxBaseTransformer {

	@Inject private CustomObjectsStore customObjsStore;

	public SLGTranslationUnit transform(final IDiscreteValueDeviation value) {
		return transformClass(value.getClass());  // hash according to class not instance
	}

	// ---------- 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 transformClass(final Class<? extends IDiscreteValueDeviation> devClass) {
		final List<Object> key = new ArrayList<>(Arrays.asList(devClass));
		final SLGTranslationUnit tu;

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

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

		return tu;
	}

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

	private SLGTranslationUnit createTranslationUnit(final Class<? extends IDiscreteValueDeviation> devClass) {
		if ((devClass == null)) {
			return new SLGTranslationUnit("UNSPECIFIED TICKS");
		} else {
			String basePath = "synthetic_gen";
			String moduleName = "ticksUtils";
			String call = "burnTicks(<params>)"; // unused
			return new SLGTranslationUnit(basePath, moduleName, call);
		}
	}

	private void doTransform(final SLGTranslationUnit tu, final Class<? extends IDiscreteValueDeviation> devClass) {
		genFiles(tu, devClass);
	}

	public void genFiles(SLGTranslationUnit tu, final Class<? extends IDiscreteValueDeviation> devClass) {
		if (isIncFileEmpty(tu)) {
			toH(tu);
		}
		if (isSrcFileEmpty(tu)) {
			toCPP(tu);
		}
		srcAppend(tu, LinuxTicksUtilsGenerator.generateTicks(devClass));
		incAppend(tu, LinuxTicksUtilsGenerator.generateTicksDeclaration(devClass));
	}

	private void toCPP(SLGTranslationUnit tu) {
		srcAppend(tu, "#include \"" + getIncFile(tu) + "\"\n");

		final ConfigModel configModel = customObjsStore.<ConfigModel>getInstance(ConfigModel.class);

		final String ticksCodeSnippet = configModel.getCustomTickImpl().getValue();
		final boolean ticksCodeEnabled = configModel.getCustomTickImpl().isEnable();
		
		final String burnTicksBody = ticksCodeEnabled ? ticksCodeSnippet : LinuxTicksUtilsGenerator.burnTicksDefault();

		srcAppend(tu, LinuxTicksUtilsGenerator.burnTicks(burnTicksBody));
		srcAppend(tu, LinuxTicksUtilsGenerator.burnTicksStatistics(configModel));

	}

	private void toH(SLGTranslationUnit tu) {
		incAppend(tu, LinuxTicksUtilsGenerator.burnTicksDeclaration());
		incAppend(tu, LinuxTicksUtilsGenerator.burnTicksStatisticsDecleration());
	}

}
