/**
 ********************************************************************************
 * Copyright (c) 2015-2020 Robert Bosch GmbH and others.
 *
 * 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.amalthea.converters081.impl;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.app4mc.amalthea.converters.common.ServiceConstants;
import org.eclipse.app4mc.amalthea.converters.common.base.ICache;
import org.eclipse.app4mc.amalthea.converters.common.base.IConverter;
import org.eclipse.app4mc.amalthea.converters.common.converter.AbstractConverter;
import org.eclipse.app4mc.amalthea.converters.common.utils.AmaltheaNamespaceRegistry;
import org.eclipse.app4mc.amalthea.converters.common.utils.HelperUtil;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class is responsible for converting the Stimuli Model elements from 0.8.0 to 0.8.1 version format of AMALTHEA model
 *
 * @author mez2rng
 *
 */
@Component(
		property = {
			ServiceConstants.INPUT_MODEL_VERSION_PROPERTY + "=0.8.0",
			ServiceConstants.OUTPUT_MODEL_VERSION_PROPERTY + "=0.8.1"},
		service = IConverter.class)

public class StimuliConverter extends AbstractConverter {

	private static final Logger LOGGER = LoggerFactory.getLogger(StimuliConverter.class);

	@Override
	@Activate
	protected void activate(Map<String, Object> properties) {
		super.activate(properties);
	}

	@Override
	public void convert(File targetFile, Map<File, Document> filename2documentMap, List<ICache> caches) {

		LOGGER.info("Migration from 0.8.0 to 0.8.1 : Executing Stimuli converter for model file : {}",
				targetFile.getName());


		final Document root = filename2documentMap.get(targetFile);

		if (root == null) {
			return;
		}
		final Element rootElement = root.getRootElement();

		updateAllModeValueListEntryElements(rootElement);

		updateAllStimulusElements(rootElement);

		updateCustomPropertiesForStimulus(rootElement);
	}

	private void updateCustomPropertiesForStimulus(Element rootElement) {

		final StringBuilder xpathBuffer = new StringBuilder();

		xpathBuffer.append(".//customProperties/value[@value]");
		xpathBuffer.append("|");
		xpathBuffer.append(".//customProperties/value/value");
		xpathBuffer.append("|");
		xpathBuffer.append(".//customProperties//values[@value]");
		xpathBuffer.append("|");
		xpathBuffer.append(".//customProperties//values/value");

		Map<String, String> namesMap=new HashMap<>();

		namesMap.put("ArrivalCurve","ArrivalCurveStimulus");
		namesMap.put("InterProcess","InterProcessStimulus");
		namesMap.put("Periodic","PeriodicStimulus");
		namesMap.put("PeriodicEvent","VariableRateStimulus");
		namesMap.put("Single","SingleStimulus");
		namesMap.put("Sporadic","SporadicStimulus");
		namesMap.put("Synthetic","SyntheticStimulus");

		final List<Element> elements = HelperUtil.getXpathResult(
				rootElement,
				xpathBuffer.toString(),
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

		for (Element element : elements) {

			Attribute typeAttribute = element.getAttribute("type", AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

			Attribute valueAttribute = element.getAttribute("value");

			Attribute hrefAttribute = element.getAttribute("href");

			/*-
			 * Case 1:  <value xsi:type="am:ReferenceObject" value="no-name?type=ArrivalCurve"/>
			 *
			 */
			if(typeAttribute !=null && valueAttribute !=null){

				String value = valueAttribute.getValue();

				final int indexOfEquals = value.indexOf('=');

				if(indexOfEquals!=-1){
					String stimulusName = value.substring(indexOfEquals+1, value.length());
					if(namesMap.containsKey(stimulusName)){
						String newValue = value.substring(0, indexOfEquals+1)+namesMap.get(stimulusName);
						valueAttribute.setValue(newValue);
					}
				}
			}

			/*-
			 * Case 2:   <value xsi:type="am:EventStimulus" href="amlt:/#foreignEventStimulus?type=EventStimulus"/>
			 */
			else if((valueAttribute == null) && (hrefAttribute !=null) && (typeAttribute !=null)){

				updateStimulusTypeAttribute(element);

				String value = hrefAttribute.getValue();

				final int indexOfEquals = value.indexOf('=');

				if(indexOfEquals!=-1){
					String stimulusName = value.substring(indexOfEquals+1, value.length());

					if(namesMap.containsKey(stimulusName)){
						String newValue = value.substring(0, indexOfEquals+1)+namesMap.get(stimulusName);
						hrefAttribute.setValue(newValue);
					}
				}
			}
		}
	}

	/**
	 * This method is used to migrate all EventStimulus elements + update type info of Stimulus elements (For further
	 * details, check : Bug 519925, Bug 519930  )
	 *
	 *
	 * @param rootElement
	 *            Amalthea root element
	 */
	private void updateAllStimulusElements(Element rootElement) {

		updateAllStimulusElementsDefinition(rootElement);

		updateAllStimulusElementsReferences(rootElement);
	}

	private void updateAllStimulusElementsReferences(Element rootElement) {

		Map<String, String> old_new_StimulusNamesMap=new HashMap<>();

		old_new_StimulusNamesMap.put("ArrivalCurve", "ArrivalCurveStimulus");
		old_new_StimulusNamesMap.put("InterProcess", "InterProcessStimulus");
		old_new_StimulusNamesMap.put("Periodic", "PeriodicStimulus");
		old_new_StimulusNamesMap.put("PeriodicEvent", "VariableRateStimulus");
		old_new_StimulusNamesMap.put("Single", "SingleStimulus");
		old_new_StimulusNamesMap.put("Sporadic", "SporadicStimulus");
		old_new_StimulusNamesMap.put("Synthetic", "SyntheticStimulus");

		final StringBuilder stimulusEventBuffer = new StringBuilder();

		stimulusEventBuffer.append("./eventModel/events[@xsi:type=\"am:StimulusEvent\"]");

		updateStimulusReferences(rootElement, old_new_StimulusNamesMap, stimulusEventBuffer, "entity",false);

		final StringBuilder processBuffer = new StringBuilder();
		processBuffer.append("./swModel/tasks");
		processBuffer.append("|");
		processBuffer.append("./swModel/isrs");

		updateStimulusReferences(rootElement, old_new_StimulusNamesMap, processBuffer, "stimuli",false);

		final StringBuilder interProcessActivationBuffer = new StringBuilder();

		interProcessActivationBuffer.append("./swModel/tasks//calls[@xsi:type=\"am:InterProcessActivation\"]");
		interProcessActivationBuffer.append("|");
		interProcessActivationBuffer.append("./swModel/isrs//calls[@xsi:type=\"am:InterProcessActivation\"]");

		updateStimulusReferences(rootElement, old_new_StimulusNamesMap, interProcessActivationBuffer, "stimulus",true);

	}

	private void updateStimulusReferences(Element rootElement, Map<String, String> old_new_StimulusNamesMap,
			final StringBuilder stimulusEventBuffer, String variableName, boolean isInterProcessActivation) {

		final List<Element> elements = HelperUtil.getXpathResult(
				rootElement,
				stimulusEventBuffer.toString(),
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

		for (Element targetElement : elements) {

			Attribute attribute = targetElement.getAttribute(variableName);

			if (attribute != null) {

				StringBuilder updatedValueBuffer = new StringBuilder();

				StringTokenizer stk = new StringTokenizer(attribute.getValue());

				while (stk.hasMoreTokens()) {

					String nextToken = stk.nextToken();

					updatedValueBuffer.append(getUpdatedStimulusReference(nextToken, old_new_StimulusNamesMap,isInterProcessActivation) + " ");
				}

				String trimmedValue = updatedValueBuffer.toString().trim();

				if(trimmedValue.length()!=0){
					attribute.setValue(trimmedValue);
				}else{
					attribute.detach();
				}
			}

			List<Element> children = HelperUtil.getXpathResult(
					targetElement,
					"./"+variableName,
					Element.class,
					AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

			for (Element element : children) {

				if(isInterProcessActivation){

					//Note: in case of InterProcessActivation, only InterProcessStimulus is supported (for details refer : 519930)
					String attributeValue = element.getAttributeValue("type", AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

					if(attributeValue!=null && ! attributeValue.equals("InterProcess") ){
						element.detach();
						continue;
					}
				}

				/*-- element will also have the type information, if in the model, contents are defined using its super class */

				updateStimulusTypeAttribute(element);


				/*--- below code is used to update the references */
				Attribute hrefAttribute = element.getAttribute("href");

				if (hrefAttribute != null) {
					String value = hrefAttribute.getValue();

					String updatedValue = getUpdatedStimulusReference(value, old_new_StimulusNamesMap,isInterProcessActivation);

					if (!value.equals(updatedValue)) {
						hrefAttribute.setValue(updatedValue);
					}
				}
			}

			/*-
			 * update root elements type for InterProcessActivation as per the meta model change in 0.8.1:
			 */

			if(isInterProcessActivation){
				Attribute typeAttribute = targetElement.getAttribute("type",AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

				if (typeAttribute != null) {

					String typeValue = typeAttribute.getValue();

					if(typeValue.equals("am:InterProcessActivation")){
						typeAttribute.setValue("am:InterProcessTrigger");
					}
				}
			}
		}
	}

	private String  getUpdatedStimulusReference(String token, Map<String, String> old_new_StimulusNamesMap, boolean isInterProcessActivation) {

		final int indexOfEquals = token.indexOf('=');

		if(indexOfEquals!=-1){
			String stimulusType = token.substring(indexOfEquals+1, token.length());

			//Note: in case of InterProcessActivation, only InterProcessStimulus is supported (for details refer : 519930)
			if(isInterProcessActivation && ! stimulusType.equals("InterProcess")){
				return "";
			}

			if(old_new_StimulusNamesMap.containsKey(stimulusType)) {
				return	token.substring(0, indexOfEquals+1)+old_new_StimulusNamesMap.get(stimulusType);
			}
		}

		return token;
	}

	private void updateAllStimulusElementsDefinition(Element rootElement) {
		final StringBuilder xpathBuffer = new StringBuilder();

		xpathBuffer.append("./stimuliModel/stimuli");

		final List<Element> stimulusElements = HelperUtil.getXpathResult(
				rootElement,
				xpathBuffer.toString(),
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

		for (Element stimulusElement : stimulusElements) {

			updateStimulusTypeAttribute(stimulusElement);


		}
	}

	/**
	 * This method is used to update the type attribute of both Stimulus definition and references
	 * @param stimulusElement
	 */
	private void updateStimulusTypeAttribute(Element stimulusElement) {
		Attribute typeAttribute = stimulusElement.getAttribute("type", AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

		if (typeAttribute != null) {

			String stimulusType = typeAttribute.getValue();

			if (stimulusType.equals("am:EventStimulus")) {

				/*-Model migration of EventStimulus element as per Bug 519925*/

				updateEventStimulus(stimulusElement);

			} else if (stimulusType.equals("am:ArrivalCurve")) {

				typeAttribute.setValue("am:ArrivalCurveStimulus");

			} else if (stimulusType.equals("am:InterProcess")) {

				typeAttribute.setValue("am:InterProcessStimulus");

			} else if (stimulusType.equals("am:Periodic")) {

				typeAttribute.setValue("am:PeriodicStimulus");

			} else if (stimulusType.equals("am:PeriodicEvent")) {

				typeAttribute.setValue("am:VariableRateStimulus");

			} else if (stimulusType.equals("am:Single")) {

				typeAttribute.setValue("am:SingleStimulus");

			} else if (stimulusType.equals("am:Sporadic")) {

				typeAttribute.setValue("am:SporadicStimulus");

			} else if (stimulusType.equals("am:Synthetic")) {

				typeAttribute.setValue("am:SyntheticStimulus");

			}
		}
	}

	/**
	 * This method is used to migrate all EventStimulus elements + (For further
	 * details, check : Bug 519925  )
	 * @param stimulusElement
	 */
	private void updateEventStimulus(Element stimulusElement) {
		Attribute triggerAttribute = stimulusElement.getAttribute("trigger");

		if(triggerAttribute!=null){
			 triggerAttribute.setName("triggeringEvents");
		}

		List<Element> triggerElements = stimulusElement.getChildren("trigger");

		if(triggerElements !=null ){
			for (Element triggerElement : triggerElements) {
				triggerElement.setName("triggeringEvents");
			}
		}
	}

	/**
	 * This method is used to migrate all ModeValueListEntry elements (For further
	 * details, check : Bug 519860 )
	 *
	 *
	 * @param rootElement
	 *            Amalthea root element
	 */
	private void updateAllModeValueListEntryElements(Element rootElement) {

		final StringBuilder xpathBuffer = new StringBuilder();

		xpathBuffer.append("./stimuliModel/stimuli/setModeValueList/entries");
		xpathBuffer.append("|");
		xpathBuffer.append("./stimuliModel/stimuli/enablingModeValueList/entries");
		xpathBuffer.append("|");
		xpathBuffer.append("./stimuliModel/stimuli/disablingModeValueList/entries");

		final List<Element> modeValueListEntryElements = HelperUtil.getXpathResult(
				rootElement,
				xpathBuffer.toString(),
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));

		for (Element modeValueListEntry : modeValueListEntryElements) {
			modeValueListEntry.setAttribute("type", "am:ModeValue", AmaltheaNamespaceRegistry.getGenericNamespace("xsi"));
		}

	}

}
