/**
 * 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.commons.m2t.generators;

import org.eclipse.app4mc.amalthea.model.impl.DiscreteValueConstantImpl;
import org.eclipse.app4mc.amalthea.model.impl.DiscreteValueStatisticsImpl;
import org.eclipse.app4mc.slg.config.ConfigModel;
import org.eclipse.app4mc.slg.config.TickType;
import org.eclipse.app4mc.transformation.util.OutputBuffer;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.IntegerRange;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Objects;

public class TicksUtilsTranslationUnit extends TranslationUnit {
	private static final Logger LOG = LoggerFactory.getLogger(TicksUtilsTranslationUnit.class);

	public static String getModulePathStatic() {
		return "synthetic_gen" + "/" + getModuleNameStatic();
	}

	public static String getMakeFilePathStatic() {
		return getModulePathStatic() + "/" + "CMakeLists.txt";
	}

	public static String getModuleNameStatic() {
		return "ticksUtils";
	}

	public static String getLibName() {
		return "TICKS_UTILS";
	}

	public String getModuleName() {
		return TicksUtilsTranslationUnit.getModuleNameStatic();
	}

	public CharSequence getExecCall(final String params) {
		StringConcatenation _builder = new StringConcatenation();
		_builder.append("executeTicks_");
		String _last = IterableExtensions
				.<String>last(((Iterable<String>) Conversions.doWrapArray(this.valueClass.toString().split("\\."))));
		_builder.append(_last);
		_builder.append("(");
		_builder.append(params);
		_builder.append(")");
		return _builder;
	}

	public String getIncFile() {
		return this.getModuleName() + ".h";
	}

	private final ConfigModel configModel;

	private final Object valueClass;

	private OutputBuffer outputBuffer;

	public TicksUtilsTranslationUnit(final OutputBuffer outputBuffer, final ConfigModel configModel,
			final Object valueClass) {
		super();
		this.configModel = configModel;
		this.valueClass = valueClass;
		this.outputBuffer = outputBuffer;
		this.genFiles();
	}

	public boolean genFiles() {
		boolean _xblockexpression = false;
		{
			boolean _isIncFileEmpty = this.isIncFileEmpty();
			if (_isIncFileEmpty) {
				this.toH();
			}
			boolean _isSrcFileEmpty = this.isSrcFileEmpty();
			if (_isSrcFileEmpty) {
				this.toCPP();
			}
			this.srcAppend(this.generateTicks(this.valueClass));
			_xblockexpression = this.incAppend(this.generateTicksDecleration(this.valueClass));
		}
		return _xblockexpression;
	}

	private boolean toCPP() {
		boolean _xblockexpression = false;
		{
			String _incFile = this.getIncFile();
			String _plus = ("#include \"" + _incFile);
			String _plus_1 = (_plus + "\"\n");
			this.srcAppend(_plus_1);
			final String ticksCodeSnippet = this.configModel.getCustomTickImpl().getValue();
			String _xifexpression = null;
			boolean _isEnable = this.configModel.getCustomTickImpl().isEnable();
			if (_isEnable) {
				_xifexpression = ticksCodeSnippet;
			} else {
				_xifexpression = this.burnTicksDefault().toString();
			}
			final String burnTicksBody = _xifexpression;
			this.srcAppend(this.burnTicks(burnTicksBody).toString());
			_xblockexpression = this.srcAppend(this.burnTicksStatistics(this.configModel).toString());
		}
		return _xblockexpression;
	}

	private boolean toH() {
		boolean _xblockexpression = false;
		{
			this.incAppend(this.burnTicksDecleration().toString());
			_xblockexpression = this.incAppend(this.burnTicksStatisticsDecleration().toString());
		}
		return _xblockexpression;
	}

	private String generateTicks(final Object valueClass) {
		String _switchResult = null;
		boolean _matched = false;
		if (Objects.equal(valueClass, DiscreteValueConstantImpl.class)) {
			_matched = true;
			StringConcatenation _builder = new StringConcatenation();
			_builder.append("void ");
			CharSequence _execCall = this.getExecCall("int ticks");
			_builder.append(_execCall);
			_builder.append(" {");
			_builder.newLineIfNotEmpty();
			_builder.append("\t");
			_builder.append("burnTicks(ticks);");
			_builder.newLine();
			_builder.append("}");
			_builder.newLine();
			_builder.newLine();
			_switchResult = _builder.toString();
		}
		if (!_matched) {
			if (Objects.equal(valueClass, DiscreteValueStatisticsImpl.class)) {
				_matched = true;
				StringConcatenation _builder_1 = new StringConcatenation();
				_builder_1.append("void ");
				CharSequence _execCall_1 = this.getExecCall("double average, int lowerBound, int upperBound");
				_builder_1.append(_execCall_1);
				_builder_1.append(" {");
				_builder_1.newLineIfNotEmpty();
				_builder_1.append("\t");
				_builder_1.append("burnTicksStatistics(average, lowerBound, upperBound);");
				_builder_1.newLine();
				_builder_1.append("}");
				_builder_1.newLine();
				_builder_1.newLine();
				_switchResult = _builder_1.toString();
			}
		}
		if (!_matched) {
			String _xblockexpression = null;
			{
				String _string = valueClass.toString();
				String _plus = ("Unsupported ticks type is used : " + _string);
				TicksUtilsTranslationUnit.LOG.error(_plus);
				_xblockexpression = "";
			}
			_switchResult = _xblockexpression;
		}
		return _switchResult;
	}

	private CharSequence burnTicks(final String burnTicksBody) {
		StringConcatenation _builder = new StringConcatenation();
		_builder.append("void burnTicks(int ticks) {");
		_builder.newLine();
		_builder.append("\t");
		_builder.append(burnTicksBody, "\t");
		_builder.newLineIfNotEmpty();
		_builder.append("}");
		_builder.newLine();
		_builder.newLine();
		return _builder;
	}

	private String chooseTicks(final ConfigModel configModel) {
		String _switchResult = null;
		TickType _defaultTickType = configModel.getDefaultTickType();
		if (_defaultTickType != null) {
			switch (_defaultTickType) {
			case MINIMUM:
				_switchResult = "lowerBound";
				break;
			case MAXIMUM:
				_switchResult = "upperBound";
				break;
			case AVERAGE:
				_switchResult = "(int)average";
				break;
			default:
				_switchResult = "(int)average";
				break;
			}
		} else {
			_switchResult = "(int)average";
		}
		return _switchResult;
	}

	private CharSequence burnTicksStatistics(final ConfigModel configModel) {
		StringConcatenation _builder = new StringConcatenation();
		_builder.append("void burnTicksStatistics(double average, int lowerBound, int upperBound) {");
		_builder.newLine();
		_builder.append("\t");
		_builder.append("burnTicks(");
		String _chooseTicks = this.chooseTicks(configModel);
		_builder.append(_chooseTicks, "\t");
		_builder.append(");");
		_builder.newLineIfNotEmpty();
		_builder.append("}");
		_builder.newLine();
		_builder.newLine();
		return _builder;
	}

	private CharSequence burnTicksDefault() {
		StringConcatenation _builder = new StringConcatenation();
		_builder.append("\t");
		_builder.append("// default implementation of tick burning");
		_builder.newLine();
		_builder.append("\t");
		_builder.append("int numLoops = ticks / 400; ");
		_builder.newLine();
		_builder.append("#\tif defined (__x86_64__)");
		_builder.newLine();
		_builder.append(" \t");
		_builder.append("for (int i = 0; i < numLoops; i++) {");
		_builder.newLine();
		{
			IntegerRange _upTo = new IntegerRange(1, 400);
			for (final Integer i : _upTo) {
				_builder.append(" \t\t");
				_builder.append("__asm volatile(\"nop\");");
				_builder.newLine();
			}
		}
		_builder.append(" \t\t");
		_builder.append("}");
		_builder.newLine();
		_builder.append("#\telif defined (__x86_32__) \t\t");
		_builder.newLine();
		_builder.append(" \t\t");
		_builder.append("for (int i = 0; i < numLoops; i++) {");
		_builder.newLine();
		{
			IntegerRange _upTo_1 = new IntegerRange(1, 400);
			for (final Integer i_1 : _upTo_1) {
				_builder.append(" \t\t\t \t");
				_builder.append("__asm volatile(\"mov r0, r0\");");
				_builder.newLine();
			}
		}
		_builder.append(" \t\t\t\t");
		_builder.append("}");
		_builder.newLine();
		_builder.append("#\telif defined (__aarch64__) \t\t");
		_builder.newLine();
		_builder.append(" \t");
		_builder.append("for (int i = 0; i < numLoops; i++) {");
		_builder.newLine();
		{
			IntegerRange _upTo_2 = new IntegerRange(1, 400);
			for (final Integer i_2 : _upTo_2) {
				_builder.append(" \t");
				_builder.append("__asm volatile(\"mov x0, x0\");");
				_builder.newLine();
			}
		}
		_builder.append("\t");
		_builder.append("}");
		_builder.newLine();
		_builder.append("#\tendif");
		_builder.newLine();
		return _builder;
	}

	private CharSequence burnTicksDecleration() {
		StringConcatenation _builder = new StringConcatenation();
		_builder.append("void burnTicks(int ticks);");
		_builder.newLine();
		_builder.newLine();
		return _builder;
	}

	private CharSequence burnTicksStatisticsDecleration() {
		StringConcatenation _builder = new StringConcatenation();
		_builder.append("void burnTicksStatistics(double average, int lowerBound, int upperBound);");
		_builder.newLine();
		_builder.newLine();
		return _builder;
	}

	private String generateTicksDecleration(final Object valueClass) {
		String _switchResult = null;
		boolean _matched = false;
		if (Objects.equal(valueClass, DiscreteValueConstantImpl.class)) {
			_matched = true;
			StringConcatenation _builder = new StringConcatenation();
			_builder.append("void ");
			CharSequence _execCall = this.getExecCall("int ticks");
			_builder.append(_execCall);
			_builder.append(";");
			_builder.newLineIfNotEmpty();
			_builder.newLine();
			_switchResult = _builder.toString();
		}
		if (!_matched) {
			if (Objects.equal(valueClass, DiscreteValueStatisticsImpl.class)) {
				_matched = true;
				StringConcatenation _builder_1 = new StringConcatenation();
				_builder_1.append("void ");
				CharSequence _execCall_1 = this.getExecCall("double average, int lowerBound, int upperBound");
				_builder_1.append(_execCall_1);
				_builder_1.append(";");
				_builder_1.newLineIfNotEmpty();
				_builder_1.newLine();
				_switchResult = _builder_1.toString();
			}
		}
		if (!_matched) {
			String _xblockexpression = null;
			{
				String _string = valueClass.toString();
				String _plus = ("Unsupported ticks type is used : " + _string);
				TicksUtilsTranslationUnit.LOG.error(_plus);
				_xblockexpression = "";
			}
			_switchResult = _xblockexpression;
		}
		return _switchResult;
	}

	public String getBasePath() {
		return "synthetic_gen";
	}

	public String getModulePath() {
		String _basePath = this.getBasePath();
		String _plus = (_basePath + "/");
		String _moduleName = this.getModuleName();
		return (_plus + _moduleName);
	}

	@Override
	public String getSrcFile() {
		String _moduleName = this.getModuleName();
		return (_moduleName + ".cpp");
	}

	public String getIncPath() {
		String _modulePath = this.getModulePath();
		String _plus = (_modulePath + "/_inc/");
		String _incFile = this.getIncFile();
		return (_plus + _incFile);
	}

	public String getSrcPath() {
		String _modulePath = this.getModulePath();
		String _plus = (_modulePath + "/_src/");
		String _srcFile = this.getSrcFile();
		return (_plus + _srcFile);
	}

	public boolean isIncFileEmpty() {
		String _modulePath = this.getModulePath();
		String _plus = (_modulePath + "/_inc/");
		String _moduleName = this.getModuleName();
		String _plus_1 = (_plus + _moduleName);
		boolean _bufferExists = this.outputBuffer.bufferExists("INC", _plus_1);
		return (!_bufferExists);
	}

	public boolean isSrcFileEmpty() {
		String _modulePath = this.getModulePath();
		String _plus = (_modulePath + "/_src/");
		String _moduleName = this.getModuleName();
		String _plus_1 = (_plus + _moduleName);
		boolean _bufferExists = this.outputBuffer.bufferExists("SRC", _plus_1);
		return (!_bufferExists);
	}

	public boolean incAppend(final String str) {
		String _modulePath = this.getModulePath();
		String _plus = (_modulePath + "/_inc/");
		String _moduleName = this.getModuleName();
		String _plus_1 = (_plus + _moduleName);
		return this.outputBuffer.appendTo("INC", _plus_1, str);
	}

	public boolean srcAppend(final String str) {
		String _modulePath = this.getModulePath();
		String _plus = (_modulePath + "/_src/");
		String _moduleName = this.getModuleName();
		String _plus_1 = (_plus + _moduleName);
		return this.outputBuffer.appendTo("SRC", _plus_1, str);
	}
}
