/**
 ********************************************************************************
 * Copyright (c) 2018-2022 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.model.provider;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.eclipse.app4mc.amalthea.model.ActivityGraph;
import org.eclipse.app4mc.amalthea.model.AmaltheaPackage;
import org.eclipse.app4mc.amalthea.model.AmaltheaServices;
import org.eclipse.app4mc.amalthea.model.CallArgument;
import org.eclipse.app4mc.amalthea.model.Component;
import org.eclipse.app4mc.amalthea.model.ComponentInstance;
import org.eclipse.app4mc.amalthea.model.ComponentPort;
import org.eclipse.app4mc.amalthea.model.Composite;
import org.eclipse.app4mc.amalthea.model.DataDependency;
import org.eclipse.app4mc.amalthea.model.DirectionType;
import org.eclipse.app4mc.amalthea.model.EnumMode;
import org.eclipse.app4mc.amalthea.model.HwAccessElement;
import org.eclipse.app4mc.amalthea.model.HwAccessPath;
import org.eclipse.app4mc.amalthea.model.HwFeatureCategory;
import org.eclipse.app4mc.amalthea.model.HwPathElement;
import org.eclipse.app4mc.amalthea.model.INamed;
import org.eclipse.app4mc.amalthea.model.ISystem;
import org.eclipse.app4mc.amalthea.model.InterfaceKind;
import org.eclipse.app4mc.amalthea.model.LocalModeLabel;
import org.eclipse.app4mc.amalthea.model.LocalModeLabelRef;
import org.eclipse.app4mc.amalthea.model.LocalModeValue;
import org.eclipse.app4mc.amalthea.model.Mode;
import org.eclipse.app4mc.amalthea.model.ModeLabel;
import org.eclipse.app4mc.amalthea.model.ModeLabelAccess;
import org.eclipse.app4mc.amalthea.model.ModeLiteral;
import org.eclipse.app4mc.amalthea.model.ModeLiteralConst;
import org.eclipse.app4mc.amalthea.model.ModeValue;
import org.eclipse.app4mc.amalthea.model.NumericMode;
import org.eclipse.app4mc.amalthea.model.Process;
import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
import org.eclipse.app4mc.amalthea.model.QualifiedPort;
import org.eclipse.app4mc.amalthea.model.Runnable;
import org.eclipse.app4mc.amalthea.model.RunnableCall;
import org.eclipse.app4mc.amalthea.model.RunnableParameter;
import org.eclipse.app4mc.amalthea.model.util.SoftwareUtil;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.UniqueEList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ItemPropertyDescriptor;

public class CustomPropertyDescriptorService {

	// Suppress default constructor
	private CustomPropertyDescriptorService() {
		throw new IllegalStateException("Utility class");
	}

	// *****************************************************************************
	//				NeedEntry Property Descriptors
	// *****************************************************************************

	public static Collection<String> getNeedEntryValuesForKey(final Object object) {
		final UniqueEList<String> choiceOfValues = new UniqueEList<>();

		// get HW feature categories
		final EClass type = AmaltheaPackage.eINSTANCE.getHwFeatureCategory();
		final Collection<EObject> objects = ItemPropertyDescriptor.getReachableObjectsOfType(((EObject) object), type);

		// empty entry
		choiceOfValues.add(null);

		// entries: names of feature categories
		objects.stream()
			.map(obj -> ((HwFeatureCategory) obj).getName())
			.filter(Objects::nonNull)
			.sorted()
			.forEachOrdered(choiceOfValues::add);
		
		return choiceOfValues;
	}

	// *****************************************************************************
	//				CallArgument Property Descriptors
	// *****************************************************************************

	public static Collection<RunnableParameter> getCallArgumentValuesForParameter(final Object object) {
		if (object instanceof CallArgument) {
			
			// *** Parameters of called runnable
			
			RunnableCall call = ((CallArgument) object).getContainingCall();
			if (call != null && call.getRunnable() != null) {
				List<RunnableParameter> parameters = call.getRunnable().getParameters();
				if (! parameters.isEmpty()) {
					// build result list
					UniqueEList<RunnableParameter> choiceOfValues = new UniqueEList<>();
					choiceOfValues.add(null); // empty entry at first position
					choiceOfValues.addAll(parameters);
					return choiceOfValues;
				}
			}
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				DataDependency Property Descriptors
	// *****************************************************************************

	public static Collection<RunnableParameter> getDataDependencyValuesForParameters(final Object object) {
		if (object instanceof DataDependency) {

			// *** Parameters (in, inout) of containing runnable

			final Runnable runnable = ((DataDependency) object).getContainingRunnable();
			if (runnable != null) {
				// build result list
				final List<RunnableParameter> choiceOfValues = new BasicEList<>();
				runnable.getParameters().stream()
					.filter(e -> e.getDirection() == DirectionType.IN || e.getDirection() == DirectionType.INOUT)
					.forEachOrdered(choiceOfValues::add);
				return choiceOfValues;
			}
		}
		return Collections.emptyList();
	}

	public static Collection<CallArgument> getDataDependencyValuesForCallArguments(final Object object) {
		if (object instanceof DataDependency) {
			final DataDependency dependency = (DataDependency) object;

			// *** CallArguments (out, inout) of calls in the same graph

			ActivityGraph graph = null;
			// first: check if a runnable graph is available
			Runnable runnable = dependency.getContainingRunnable();
			if (runnable != null && runnable.getActivityGraph() != null) {
				graph = runnable.getActivityGraph();
			} else {
				// second: check if a process graph is available
				Process process = AmaltheaServices.getContainerOfType(dependency, Process.class);
				if (process != null && process.getActivityGraph() != null) {
					graph = process.getActivityGraph();
				}
			}

			if (graph != null) {
				List<DirectionType> dirList = Arrays.asList(DirectionType.OUT, DirectionType.INOUT);
				return SoftwareUtil.collectActivityGraphItems(graph, null, RunnableCall.class).stream()
					.map(RunnableCall::getArguments)
					.flatMap(Collection::stream)
					.filter(arg -> arg.getParameter() != null)
					.filter(arg -> dirList.contains(arg.getParameter().getDirection()))
					.collect(Collectors.toList());
			}
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				private helper methods for modes
	// *****************************************************************************

	private static Collection<String> collectModeValueStrings(Mode mode) {
		// Identify mode and possible values

		if (mode instanceof NumericMode) return null; // standard editor

		if (mode instanceof EnumMode) {
			return ((EnumMode) mode).getLiterals().stream()
					.map(INamed::getName)
					.filter(Objects::nonNull)
					.collect(Collectors.toList());
		}

		return Collections.emptyList();
	}

	// *****************************************************************************
	//				ModeValue Property Descriptors
	// *****************************************************************************

	public static Collection<String> getValuesForModeValue(final Object object) {
		if (object instanceof ModeValue) {
			ModeLabel label = ((ModeValue) object).getLabel();

			if (label != null) {
				return collectModeValueStrings(label.getMode());
			}
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				ModeLabel Property Descriptors
	// *****************************************************************************

	public static Collection<String> getInitialValuesForModeLabel(final Object object) {
		if (object instanceof ModeLabel) {
			return collectModeValueStrings(((ModeLabel) object).getMode());
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				ModeLabelAccess Property Descriptors
	// *****************************************************************************

	public static Collection<String> getValuesForModeLabelAccess(final Object object) {
		if (object instanceof ModeLabelAccess) {
			ModeLabel label = ((ModeLabelAccess) object).getData();

			if (label != null) {
				return collectModeValueStrings(label.getMode());
			}
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				LocalModeLabel Default Property Descriptors
	// *****************************************************************************

	public static Collection<String> getDefaultValuesForLocalModeLabel(final Object object) {
		if (object instanceof LocalModeLabel) {
			return collectModeValueStrings(((LocalModeLabel) object).getMode());
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				ModeLiteralConst Property Descriptors
	// *****************************************************************************

	public static Collection<ModeLiteral> getValuesForModeLiteralConst(final Object object) {
		if (object instanceof ModeLiteralConst) {
			LocalModeValue container = AmaltheaServices.getContainerOfType((ModeLiteralConst) object, LocalModeValue.class);

			if (container != null && container.getLabel() != null) {
				Mode mode = container.getLabel().getMode();

				if (mode instanceof EnumMode) {
					return ((EnumMode) mode).getLiterals().stream()
							.filter(Objects::nonNull)
							.collect(Collectors.toList());
				}
			}
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				private helper methods for local mode labels
	// *****************************************************************************

	private static Collection<LocalModeLabel> getLocalLabelsOfRunnable(final Runnable runnable) {
		if (runnable != null) {
			List<LocalModeLabel> choices = new BasicEList<>();
			choices.addAll(runnable.getLocalLabels());
			return choices;
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				LocalModeValue Label Property Descriptors
	// *****************************************************************************

	public static Collection<LocalModeLabel> getLabelsForLocalModeValue(final Object object) {
		if (object instanceof LocalModeValue) {
			LocalModeValue localModeValue = (LocalModeValue) object;

			if (localModeValue.eContainer() instanceof RunnableCall) {
				// context of a runnable call -> get local labels of called runnable
				Runnable runnable = ((RunnableCall) localModeValue.eContainer()).getRunnable();
				return getLocalLabelsOfRunnable(runnable);
			} else {
				// local runnable context
				Runnable runnable = AmaltheaServices.getContainerOfType(localModeValue, Runnable.class);
				return getLocalLabelsOfRunnable(runnable);
			}
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				LocalModeLabelRef Value Property Descriptors
	// *****************************************************************************

	public static Collection<LocalModeLabel> getValuesForLocalModeLabelRef(final Object object) {
		if (object instanceof LocalModeLabelRef) {
			Runnable runnable = AmaltheaServices.getContainerOfType((LocalModeLabelRef) object, Runnable.class);
			return getLocalLabelsOfRunnable(runnable);
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				HwAccessPath Property Descriptors
	// *****************************************************************************

	public static Collection<HwPathElement> filterValuesForPathElements(final Object object, final Collection<?> choices) {
		if (object instanceof HwAccessPath) {
			HwAccessElement accessElement = ((HwAccessPath) object).getContainingAccessElement();

			if (accessElement != null) {
				ProcessingUnit source = accessElement.getSource();

				return choices.stream()
						.filter(HwPathElement.class::isInstance)
						.map (HwPathElement.class::cast)
						.filter(e -> e != source)	// remove source
						.collect(Collectors.toList());
			}
		}
		return Collections.emptyList();
	}

	// *****************************************************************************
	//				private helper methods for components
	// *****************************************************************************

	private static Component getComponent(final QualifiedPort qualPort) {
		if (qualPort.getInstance() == null) {
			// Get container (Composite only, System has no ports)
			return AmaltheaServices.getContainerOfType(qualPort, Composite.class);
		} else {
			// Get type of instance (Component)
			return qualPort.getInstance().getType();
		}
	}

	// *****************************************************************************
	//				QualifiedPort Property Descriptors
	// *****************************************************************************

	public static Collection<ComponentInstance> getValuesForComponentInstance(final Object object) {
		if (object instanceof QualifiedPort) {
			// Get container (System or Composite)
			ISystem container = AmaltheaServices.getContainerOfType((EObject) object, ISystem.class);

			if (container != null) {
				List<ComponentInstance> choices = new BasicEList<>();
				choices.add(null);	// represents the containing component
				choices.addAll(container.getComponentInstances());
				return choices;
			}
		}
		return Collections.emptyList();
	}

	public static Collection<ComponentPort> getValuesForComponentPort(final Object object) {
		if (object instanceof QualifiedPort) {
			QualifiedPort qPort = (QualifiedPort) object;
			Component component = getComponent(qPort);
			if (component != null) {
				List<ComponentPort> choices = new BasicEList<>();
				choices.add(null);
				choices.addAll(filterPortList(component.getPorts(), qPort));
				return choices;
			}
		}
		return Collections.emptyList();
	}

	private static List<ComponentPort> filterPortList(final List<ComponentPort> ports, final QualifiedPort qualPort) {
		final boolean isInnerPort = (qualPort.getInstance() != null);
		final List<InterfaceKind> provideList = Arrays.asList(
				InterfaceKind.PROVIDES, InterfaceKind.PROVIDES_REQUIRES, InterfaceKind._UNDEFINED_);
		final List<InterfaceKind> requireList = Arrays.asList(
				InterfaceKind.REQUIRES, InterfaceKind.PROVIDES_REQUIRES, InterfaceKind._UNDEFINED_);

		EStructuralFeature feature = qualPort.eContainingFeature();
		AmaltheaPackage amPackage = AmaltheaPackage.eINSTANCE;

		if (amPackage.getConnector_SourcePort().equals(feature)) {
			if (isInnerPort) {
				return ports.stream().filter(e -> provideList.contains(e.getKind())).collect(Collectors.toList());
			} else {
				return ports.stream().filter(e -> requireList.contains(e.getKind())).collect(Collectors.toList());
			}
		}

		if (amPackage.getConnector_TargetPort().equals(feature)) {
			if (isInnerPort) {
				return ports.stream().filter(e -> requireList.contains(e.getKind())).collect(Collectors.toList());
			} else {
				return ports.stream().filter(e -> provideList.contains(e.getKind())).collect(Collectors.toList());
			}
		}

		if (amPackage.getISystem_GroundedPorts().equals(feature)) {
			if (isInnerPort) {
				return ports;
			} else {
				return Collections.emptyList();
			}
		}

		return Collections.emptyList();
	}

}
