/**
 ********************************************************************************
 * 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.ArrayList;
import java.util.Collection;
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.eclipse.app4mc.amalthea.converters081.utils.ConstraintElementsCacheBuilder;
import org.eclipse.app4mc.amalthea.converters081.utils.ConstraintElementsCacheEnum;
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 Constraints 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 ConstraintsConverter extends AbstractConverter {

	private static final String AMLT_PREFIX = "amlt:/#";
	private static final String HREF = "href";
	private static final String TYPE = "type";
	private static final String XSI = "xsi";
	private static final String VALUE = "value";
	private static final String SCOPE = "scope";
	private static final String EVENT_CHAIN = "eventChain";

	private static final Logger LOGGER = LoggerFactory.getLogger(ConstraintsConverter.class);

	private ConstraintElementsCacheBuilder cache;

	@Override
	@Activate
	protected void activate(Map<String, Object> properties) {
		super.activate(properties);
	}

	@Override
	public void convert(File targetFile, Map<File, Document> fileDocumentMapping, List<ICache> caches) {

		LOGGER.info("Migration from 0.8.0 to 0.8.1 : Executing Constraints converter for model file : {}",
				targetFile.getName());

		this.cache = getConstraintElementsCacheBuilder(caches);
		if (this.cache == null) {
			throw new IllegalStateException("ConstraintElementsCacheBuilder is not built and Object of it is not available in Converters");
		}

		final Document root = fileDocumentMapping.get(targetFile);

		if (root == null) {
			return;
		}
		final Element rootElement = root.getRootElement();

		updateEventChainElementDefinitions_and_references(rootElement);
	}

	/**
	 * This method is used for the migration of EventChain definitions and references present inside the Constraints
	 * model (For further details, check : Bug 518119 )
	 *
	 * @param rootElement
	 *            Amalthea root element
	 */
	private void updateEventChainElementDefinitions_and_references(final Element rootElement) {
		final List<Element> rootEventChainElements = HelperUtil.getXpathResult(
				rootElement,
				"./constraintsModel/eventChains",
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

		final List<String> allRootEventChainElements = getAllRootEventChainElements();

		if (! rootEventChainElements.isEmpty()) {
			for (final Element rootEventChainElement : rootEventChainElements) {
				final List<Element> subEventChainElements = HelperUtil.getXpathResult(
						rootEventChainElement,
						".//*[@xsi:type=\"am:SubEventChain\"]",
						Element.class,
						AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

				for (final Element subEventChainElement : subEventChainElements) {

					final Attribute typeAttribute = subEventChainElement.getAttribute(TYPE,
							AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

					if (typeAttribute != null) {
						typeAttribute.setValue("am:EventChainContainer");
					}
				}

				updateEventChainReferences(allRootEventChainElements, rootEventChainElement);
			}
		}

		updateEventChainReferences_in_TimingConstraints(allRootEventChainElements, rootElement);
	}

	/**
	 * This method is used to migrate the contents of TimingConstraint elements of type EventChainLatencyConstraint and
	 * EventChainSynchronizationConstraint, which are present inside Constraints Model.
	 *
	 * <b>Note:</b> As a part of migration, it should be ensured that sub EventChain elements are not directly referred
	 * inside TimingConstraint elements. Till 0.8.1, it was possible to refer sub EventChain elements --> but based on
	 * this change such references are removed. To preserve the data specified by the user, reference String is stored
	 * as a CustomProperty
	 *
	 *
	 * @param allRootEventChainElements
	 *            List<String> contains the names of all the root EventChain elements (in the entire model scope)
	 * @param rootElement
	 *            Amalthea root element
	 *
	 */
	private void updateEventChainReferences_in_TimingConstraints(final List<String> allRootEventChainElements, final Element rootElement) {

		final List<Element> eventChainReferenceEleemnts = HelperUtil.getXpathResult(
				rootElement,
				"./constraintsModel/timingConstraints[@xsi:type=\"am:EventChainLatencyConstraint\" or @xsi:type=\"am:EventChainSynchronizationConstraint\"]",
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

		for (final Element timingConstraint : eventChainReferenceEleemnts) {
			final List<String> invalidEventChainRefs = new ArrayList<>();
			final Attribute eventChainsAttribute = timingConstraint.getAttribute(SCOPE);

			if (eventChainsAttribute != null) {
				boolean isRefEventChainStringsUpdated = false;
				String refEventChainStrings = eventChainsAttribute.getValue();
				final StringTokenizer stringTokenizer = new StringTokenizer(refEventChainStrings);

				while (stringTokenizer.hasMoreTokens()) {
					final String refEventChainString = stringTokenizer.nextToken();
					final String refEventChainName = refEventChainString.substring(0, refEventChainString.lastIndexOf('?'));

					/*- performing validation, to identify if childelements are referred */
					if (!allRootEventChainElements.contains(refEventChainName)) {
						isRefEventChainStringsUpdated = true;

						/*- this is the case child EventChain element is referred (Note: As per AMALTHEA 0.8.1, it is not supported)*/
						refEventChainStrings = refEventChainStrings.replace(refEventChainString, "");

						/*- adding invalid EventChain reference string to a list -> to create CustomProperty object later */
						invalidEventChainRefs.add(refEventChainString);

						if (refEventChainStrings.trim().length() == 0) {
							timingConstraint.removeAttribute(eventChainsAttribute);
						}
						logEventChainMessage_TimingConstraint(timingConstraint, refEventChainName);
					}
				}

				if (isRefEventChainStringsUpdated) {
					/*- setting the updated EventChain reference String */
					eventChainsAttribute.setValue(refEventChainStrings.trim());
				}
			}

			/*-
			 * If EventChain element is defined in other model file, then the reference inside TimingConstraint element will be generated as a separate tag in XMI
			 *
			 * Example:
			 *
			 *  <timingConstraints xsi:type="am:EventChainLatencyConstraint" name="ecl2">
			 *		<scope href="amlt:/#eventChain_from_second_file_sub_element?type=EventChain"/>
			 *	</timingConstraints>
			 *  */
			final List<Element> eventChains = timingConstraint.getChildren(SCOPE);

			if (eventChains != null) {
				for (final Element eventChainElement : eventChains) {
					final String hrefValue = eventChainElement.getAttributeValue(HREF);
					if (hrefValue != null && hrefValue.contains(AMLT_PREFIX)) {
						final String refEventChainName = hrefValue.substring(hrefValue.indexOf('#') + 1, hrefValue.indexOf('?'));
						/*- performing validation, to identify if childelements are referred */
						if (!allRootEventChainElements.contains(refEventChainName)) {
							/*- this is the case child EventChain element is referred (Note: As per AMALTHEA 0.8.1, it is not supported)*/
							timingConstraint.removeContent(eventChainElement);
							invalidEventChainRefs.add(hrefValue);
							logEventChainMessage_TimingConstraint(timingConstraint, refEventChainName);
						}
					}
				}
			}

			/*-
			 * =================== Creating CustomProperty and associating invalid EventChain reference Strings to it. This step is performed to avoid loss of data ===========
			 */
			if (! invalidEventChainRefs.isEmpty()) {
				final Element customPropertyElement = new Element("customProperties");
				customPropertyElement.setAttribute("key", SCOPE);
				final Element valueElement = new Element(VALUE);
				valueElement.setAttribute(TYPE, "am:ListObject", AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

				for (final String invalidEventChainRef : invalidEventChainRefs) {
					final Element valuesElement = new Element("values");
					valuesElement.setAttribute(TYPE, "am:StringObject", AmaltheaNamespaceRegistry.getGenericNamespace(XSI));
					valuesElement.setAttribute(VALUE, invalidEventChainRef);
					valueElement.addContent(valuesElement);
				}

				customPropertyElement.addContent(valueElement);
				timingConstraint.addContent(customPropertyElement);
			}
		}
	}


	/**
	 * This method is used to migrate the contents of EventChainReference objects which are present inside EventChain
	 * object in Constraints Model.
	 *
	 * <b>Note:</b> As a part of migration, it should be ensured that sub EventChain elements are not directly referred
	 * inside EventChainReference elements. Till 0.8.1, there was a possibility to refer sub EventChain elements --> but
	 * based on this change such references are removed. To preserve the data specified by the user, reference String is
	 * stored as a CustomProperty
	 *
	 *
	 * @param allRootEventChainElements
	 *            List<String> contains the names of all the root EventChain elements (in the entire model scope)
	 * @param rootEventChainElement
	 *            EventChain element which is directly present inside Constraints Model
	 */
	private void updateEventChainReferences(final List<String> allRootEventChainElements, final Element rootEventChainElement) {

		final List<Element> eventChainReferenceEleemnts = HelperUtil.getXpathResult(
				rootEventChainElement,
				".//*[@xsi:type=\"am:EventChainReference\"]",
				Element.class,
				AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

		for (final Element eventChainReferenceElement : eventChainReferenceEleemnts) {

			final Attribute eventChainReferenceAttribute = eventChainReferenceElement.getAttribute(EVENT_CHAIN);

			if (eventChainReferenceAttribute != null) {
				final String refEventChainString = eventChainReferenceAttribute.getValue();

				if (refEventChainString != null && refEventChainString.contains("?")) {

					final String refEventChainName = refEventChainString.substring(0,
							refEventChainString.lastIndexOf('?'));

					/*- performing validation, to identify if childelements are referred */

					/*
					 * ASSUMPTION !!! : In case of model element reference, elements name should be already encoded as a part of the reference.
					 *
					 * allRootEventChainElements -> obtained from the CacheBuilder should already contain encoded names of the EventChain elements
					 */
					if (!allRootEventChainElements.contains((refEventChainName))) {

						/*- this is the case child EventChain element is referred (Note: As per AMALTHEA 0.8.1, it is not supported)*/

						eventChainReferenceElement.removeAttribute(eventChainReferenceAttribute);

						logEventChainMessage_and_Create_CustomProperty(rootEventChainElement,
								eventChainReferenceElement, refEventChainString, refEventChainName);
					}
				}
			}

			/*-
			 * if EventChain element is defined in other model file, then the eventChain element will be generated as a separate tag in XMI
			 *
			 * Example:
			 *
			 * <segments xsi:type="am:EventChainReference">
			 *		<eventChain href="amlt:/#eventChain_from_second_file?type=EventChain"/>
			 *	</segments>
			 *
			 *  */
			final Element eventChainElement = eventChainReferenceElement.getChild(EVENT_CHAIN);

			if (eventChainElement != null) {

				final String hrefValue = eventChainElement.getAttributeValue(HREF);

				if (hrefValue != null && hrefValue.contains(AMLT_PREFIX)) {

					final String refEventChainName = hrefValue.substring(hrefValue.indexOf('#') + 1,
							hrefValue.indexOf('?'));

					/*- performing validation, to identify if childelements are referred */

					/*
					 * ASSUMPTION !!! : In case of model element reference (refEventChainName), elements name should be already encoded as a part of the reference.
					 *
					 * allRootEventChainElements -> obtained from the CacheBuilder should already contain encoded names of the EventChain elements
					 */

					if (!allRootEventChainElements.contains((refEventChainName))) {

						/*- this is the case child EventChain element is referred (Note: As per AMALTHEA 0.8.1, it is not supported)*/

						eventChainReferenceElement.removeContent(eventChainElement);

						logEventChainMessage_and_Create_CustomProperty(rootEventChainElement,
								eventChainReferenceElement, hrefValue, refEventChainName);
					}
				}
			}
		}
	}

	private void logEventChainMessage_TimingConstraint(final Element timingConstraintElement,
			final String refEventChainName) {

		LOGGER.warn("Sub EventChain : {} is referred inside TimingConstraint as \"Scope\": {}. "
				+ "As per 0.8.1, it is not valid to refer sub EventChain elements directly.\n\r"
				+ "EventChain {}'s association is removed from TimingConstraint object, and corresponding information is stored as a CustomProperty",
				HelperUtil.decodeName(refEventChainName),
				timingConstraintElement.getAttributeValue("name"),
				refEventChainName);
	}

	private void logEventChainMessage_and_Create_CustomProperty(final Element rootEventChainElement,
			final Element eventChainReferenceElement, final String refEventChainString,
			final String refEventChainName) {

		LOGGER.warn("Sub EventChain : {} is referred inside EventChainReference of EventChain : {}."
				+ " As per 0.8.1, it is not valid to refer sub EventChain elements inside EventChainReference.\n\r"
				+ " eventChain association is removed from EventChainReference object, and corresponding information is stored as a CustomProperty",
				HelperUtil.decodeName(refEventChainName),
				rootEventChainElement.getAttributeValue("name"));


		final Element customPropertyElement = new Element("customProperties");

		customPropertyElement.setAttribute("key", EVENT_CHAIN);

		final Element valueElement = new Element(VALUE);

		valueElement.setAttribute(TYPE, "am:StringObject", AmaltheaNamespaceRegistry.getGenericNamespace(XSI));

		valueElement.setAttribute(VALUE, refEventChainString);

		customPropertyElement.addContent(valueElement);

		eventChainReferenceElement.addContent(customPropertyElement);
	}

	/**
	 * This method returns the names of all root EventChain elements -- from different AMALTHEA models which are in
	 * folder scope
	 *
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private List<String> getAllRootEventChainElements() {

		ArrayList<String> rootEventChainNames = new ArrayList<>();
		Map<File, Map<String, Object>> cacheMap = this.cache.getCacheMap();

		Collection<Map<String, Object>> values = cacheMap.values();

		for (Map<String, Object> map : values) {

			Object value = map.get(ConstraintElementsCacheEnum.ROOT_EVENTCHAIN_NAMES.name());

			if (value instanceof List<?>) {
				rootEventChainNames.addAll((Collection<? extends String>) value);
			}
		}
		return rootEventChainNames;
	}

	/**
	 * This method is used to get the ConstraintElementsCacheBuilder object
	 *
	 * @param caches The list of all caches.
	 * @return ConstraintElementsCacheBuilder
	 */
	private ConstraintElementsCacheBuilder getConstraintElementsCacheBuilder(List<ICache> caches) {
		if (caches != null) {
			for (ICache c : caches) {
				if (c instanceof ConstraintElementsCacheBuilder) {
					return (ConstraintElementsCacheBuilder) c;
				}
			}
		}

		return null;
	}
}
