/**
 ********************************************************************************
 * Copyright (c) 2018-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.converters083.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

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.eclipse.app4mc.amalthea.converters.common.utils.ModelVersion;
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 HW Model elements from 0.8.2 to 0.8.3 version format of AMALTHEA model
 *
 * @author zmeer
 *
 */
@Component(
		property = {
			ServiceConstants.INPUT_MODEL_VERSION_PROPERTY + "=0.8.2",
			ServiceConstants.OUTPUT_MODEL_VERSION_PROPERTY + "=0.8.3"},
		service = IConverter.class)

public class SwConverter extends AbstractConverter {

	private static final String AM = "am";
	private static final String XSI = "xsi";
	private static final String HREF = "href";
	private static final String TYPE = "type";
	private static final String VALUE = "value";
	private static final String VALUES = "values";
	private static final String VALUE_PROVIDER = "valueProvider";

	private static final Logger LOGGER = LoggerFactory.getLogger(SwConverter.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.2 to 0.8.3 : Executing Software model converter for model file : {}",
				targetFile.getName());


		final Document root = filename2documentMap.get(targetFile);

		if (root == null) {
			return;
		}
		final Element rootElement = root.getRootElement();


		migrateModeSwitchElements(rootElement);

		migrateVariableRateActivationElements(rootElement);

		update_CustomProps_InterfacePort_Refs(rootElement);
	}

	/**
	 * This method is used to migrate the contents of VariableRateActivation based on the changes introduced as per Bug 529831
	 *
	 *
	 * @param rootElement
	 *            Amalthea root element
	 */
	private void migrateVariableRateActivationElements(Element rootElement) {

		final StringBuilder xpathBuffer = new StringBuilder();

		xpathBuffer.append("./swModel/activations[@xsi:type=\"am:VariableRateActivation\"]");

		final List<Element> variableRateActivationElements = HelperUtil.getXpathResult(
				rootElement,
				xpathBuffer.toString(),
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
				AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));

		for (Element element : variableRateActivationElements) {
			element.removeChildren("activationDeviation");
		}
	}

	/**
	 * This method is used to migrate the contents of ModeSwitch based on the changes introduced as per Bug 528934
	 *
	 *
	 * @param rootElement
	 *            Amalthea root element
	 */
	private void migrateModeSwitchElements(Element rootElement) {

		final StringBuilder xpathBuffer = new StringBuilder();

		xpathBuffer.append("./swModel/isrs/callGraph/graphEntries[@xsi:type=\"am:ModeSwitch\"]");
		xpathBuffer.append("|");
		xpathBuffer.append("./swModel/tasks/callGraph/graphEntries[@xsi:type=\"am:ModeSwitch\"]");
		xpathBuffer.append("|");
		xpathBuffer.append("./swModel/isrs/callGraph/graphEntries//items[@xsi:type=\"am:ModeSwitch\"]");
		xpathBuffer.append("|");
		xpathBuffer.append("./swModel/tasks/callGraph/graphEntries//items[@xsi:type=\"am:ModeSwitch\"]");

		xpathBuffer.append("|");

		xpathBuffer.append("./swModel/runnables//runnableItems[@xsi:type=\"am:RunnableModeSwitch\"]");

		xpathBuffer.append("|");

		xpathBuffer.append("./swModel/runnables//items[@xsi:type=\"am:RunnableModeSwitch\"]");


		final List<Element> modeSwitchElements = HelperUtil.getXpathResult(
				rootElement,
				xpathBuffer.toString(),
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
				AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));

		updateModeSwitchElement(modeSwitchElements);
	}

	private void updateModeSwitchElement(final List<Element> modeSwitchElements) {
		//Setting xsi:type value of Port
		for (Element modeSwitchElement : modeSwitchElements) {

			boolean isLocalModeLabelUsed = false;
			String modeLabelValue = null;

			Attribute valueProviderAttribute = modeSwitchElement.getAttribute(VALUE_PROVIDER);

			Element valueProviderChild = modeSwitchElement.getChild(VALUE_PROVIDER);

			if (valueProviderAttribute != null) {
				isLocalModeLabelUsed = true;

				modeLabelValue = valueProviderAttribute.getValue();

				modeSwitchElement.removeAttribute(valueProviderAttribute);

			} else if (valueProviderChild != null) {

				modeLabelValue = valueProviderChild.getAttributeValue(HREF);

				modeSwitchElement.removeContent(valueProviderChild);
			}

			//fetch  ModeSwitchEntry<GraphEntryBase>[] entries objects and migrate them

			List<Element> entriesElements = modeSwitchElement.getChildren("entries");

			for (Element entriesElement : entriesElements) {

				boolean isLocalLiteralsUsed=false;

				Attribute valuesAttribute = entriesElement.getAttribute(VALUES);
				List<Element> valuesElements = entriesElement.getChildren(VALUES);

				List<String> literals = new ArrayList<>();

				if (valuesAttribute != null) {
					isLocalLiteralsUsed = true;

					String value = valuesAttribute.getValue();

					String[] split = value.split("\\s+");

					for (String string : split) {
						literals.add(string);
					}

					// removing this attribute, as it is not there in 0.8.3
					entriesElement.removeAttribute(valuesAttribute);

				} else if (valuesElements != null) {

					for (Element valueElement : valuesElements) {
						String attributeValue = valueElement.getAttributeValue(HREF);
						if (attributeValue != null) {
							literals.add(attributeValue);
						}
					}
					// removing this attribute, as it is not there in 0.8.3
					entriesElement.removeChildren(VALUES);
				}

				// creating Condition element and adding its children

				Element conditionElement=new Element("condition");

				for (String literal : literals) {

					Element entriesElementInsideConditionElement=new Element("entries");

					entriesElementInsideConditionElement.setAttribute(TYPE, "am:ModeValue", AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

					if (modeLabelValue != null) {
						if (isLocalModeLabelUsed) {
							entriesElementInsideConditionElement.setAttribute(VALUE_PROVIDER, modeLabelValue);
						} else {
							Element valueProviderElement = new Element(VALUE_PROVIDER);

							entriesElementInsideConditionElement.addContent(valueProviderElement);
						}
					}

					if (isLocalLiteralsUsed) {
						entriesElementInsideConditionElement.setAttribute(VALUE, literal);

					} else {
						Element valueElement = new Element(VALUE);

						valueElement.setAttribute(HREF, literal);

						entriesElementInsideConditionElement.addContent(valueElement);
					}

					conditionElement.addContent(entriesElementInsideConditionElement);
				}

				entriesElement.addContent(conditionElement);
			}

			/*- now checking for recursive ModeSwitch elements and handling them

			for (Element entriesElement : entriesElements) {

				StringBuffer xpathForSubModeSwitchBuffer=new StringBuffer();
				xpathForSubModeSwitchBuffer.append("./items[@xsi:type=\"am:ModeSwitch\"]");
				xpathForSubModeSwitchBuffer.append("|");
				xpathForSubModeSwitchBuffer.append("./defaultEntry/items[@xsi:type=\"am:ModeSwitch\"]");


				final List<Element> submodeSwitchElements = this.helper.getXpathResult(entriesElement,xpathForSubModeSwitchBuffer.toString(),
						Element.class, AmaltheaNamespaceRegistry.getGenericNamespace("xsi"),AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083("am") );

						updateModeSwitchElement(submodeSwitchElements);

					}*/
		}
	}

	  private void update_CustomProps_InterfacePort_Refs(Element rootElement) {
		  final StringBuilder xpathBuffer = new StringBuilder();

			xpathBuffer.append(".//customProperties/value[@xsi:type=\"am:FInterfacePort\"]");
			xpathBuffer.append("|");
			xpathBuffer.append(".//customProperties/value/value[@xsi:type=\"am:FInterfacePort\"]");


			final List<Element> customPropsVals = HelperUtil.getXpathResult(
					rootElement,
					xpathBuffer.toString(),
					Element.class,
					AmaltheaNamespaceRegistry.getGenericNamespace(XSI),
					AmaltheaNamespaceRegistry.getNamespace(ModelVersion._083, AM));

			for (Element element : customPropsVals) {
				Attribute val = element.getAttribute(TYPE, AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
				val.setValue("am:InterfacePort");
				//TBD :
			//	replaceFInterfacePortReference(element.getAttribute("value"));

				replaceFInterfacePortReference(element.getAttribute(HREF));


			}
	  }

	  private void replaceFInterfacePortReference(Attribute attr) {
		  if(attr != null) {
				String value = attr.getValue();
				value = value.replace("=FInterfacePort", "=InterfacePort");
				attr.setValue(value);
			}
	  }

}
