/**
 ********************************************************************************
 * Copyright (c) 2015-2021 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;

import static com.google.common.base.Preconditions.checkArgument;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

/**
 * This class provides static methods for efficient model navigation, search and delete.
 * <p>
 * An {@link AmaltheaCrossReferenceAdapter} is created and attached to the root context of the model.
 * The adapter maintains an index that allows fast access to inverse references and an index based on object name.
 * <p>
 * The method {@link AmaltheaIndex#getInverseReferences getInverseReferences} is called from several
 * generated model objects to compute inverse transient references based on the incoming references.
 */
public final class AmaltheaIndex {

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

	private static final String ARG_OBJECT_MESSAGE = "Object argument is null, expected: EObject";
	private static final String ARG_COLLECTION_MESSAGE = "Collection argument is null,  expected: Collection<? extends EObject>";
	private static final String ARG_NOTIFIER_MESSAGE = "Context argument is null, expected: Notifier";
	private static final String ARG_STREAM_MESSAGE = "Stream argument is null, expected: PrintStream";
	private static final String ARG_NAME_MESSAGE = "Name argument is null, expected: String";
	private static final String ARG_PATTERN_MESSAGE = "Pattern argument is null, expected: Pattern";
	private static final String ARG_CLASS_MESSAGE = "Class argument is null, expected: Class<T extends INamed>";
	private static final String ARG_RESULT_REFERENCE_MESSAGE = "Result reference argument is null, expected: EReference";
	private static final String ARG_TARGET_REFERENCES_MESSAGE = "Target references argument is null, expected: Set<EReference>";
	private static final String ARG_TARGET_REFERENCE_MESSAGE = "Target reference argument is null, expected: EReference";

	/**
	 * Computes a list of objects that refer to an EObject via dedicated references.
	 * <p>
	 * This method is called from several generated model objects to compute
	 * an inverse transient reference based on the incoming references.
	 *
	 * @param eObject				object that implements a derived transient opposite reference
	 * @param resultEReference		opposite reference definition (resulting objects are computed)
	 * @param targetEReferences		list of incoming references
	 * @return
	 * 		EcoreEList.UnmodifiableEList &lt;T&gt;
	 */
	public static <T> EList<T> getInverseReferences(final @NonNull EObject eObject, final @NonNull EReference resultEReference,
			final @NonNull Set<@NonNull EReference> targetEReferences) {
		checkArgument(eObject != null, ARG_OBJECT_MESSAGE);
		checkArgument(resultEReference != null, ARG_RESULT_REFERENCE_MESSAGE);
		checkArgument(targetEReferences != null, ARG_TARGET_REFERENCES_MESSAGE);

		final AmaltheaCrossReferenceAdapter amaltheaAdapter = getOrCreateAmaltheaAdapter(eObject);

		// Get references from adapter

		final List<EObject> result = new ArrayList<>();
		final Collection<Setting> nonNavigableInverseReferences = amaltheaAdapter
				.getNonNavigableInverseReferences(eObject);
		for (final Setting setting : nonNavigableInverseReferences) {
			if (targetEReferences.contains(setting.getEStructuralFeature())) {
				final EObject targetEObject = setting.getEObject();
				result.add(targetEObject);
			}
		}

		// Return immutable list

		final int size = result.size();
		final Object[] values = result.toArray();
		return new EcoreEList.UnmodifiableEList<>((InternalEObject) eObject, resultEReference, size, values);
	}

	/**
	 * Returns a set of objects that refer to the given <code>eObject</code>.
	 *
	 * @param eObject
	 * @return Set of objects (EObject)
	 */
	public static Set<EObject> getReferringObjects(final @NonNull EObject eObject) {
		checkArgument(eObject != null, ARG_OBJECT_MESSAGE);

		return getOrCreateAmaltheaAdapter(eObject).getNonNavigableInverseReferences(eObject)
				.stream()
				.map(Setting::getEObject)
				.collect(Collectors.toSet());
	}

	/**
	 * Returns a type filtered set of objects that refer to the given <code>eObject</code>.
	 *
	 * @param eObject
	 * @param targetClass
	 * @return Set of objects of given type <T extends EObject>
	 */
	public static <T extends EObject> Set<T> getReferringObjects(final @NonNull EObject eObject, final @NonNull Class<T> targetClass) {
		checkArgument(eObject != null, ARG_OBJECT_MESSAGE);
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		return getOrCreateAmaltheaAdapter(eObject).getNonNavigableInverseReferences(eObject)
				.stream()
				.map(Setting::getEObject)
				.filter(targetClass::isInstance)
				.map(targetClass::cast)
				.collect(Collectors.toSet());
	}

	/**
	 * Returns a filtered set of objects that refer to the given <code>eObject</code>
	 * <p>
	 * Filters:
	 * <ul>
	 * <li>type (<code>targetClass</code>)</li>
	 * <li>reference (<code>targetEReference</code>)</li>
	 * </ul>
	 *
	 * @param eObject
	 * @param targetClass
	 * @param targetEReference
	 * @return Set of objects of given type <T extends EObject>
	 */
	public static <T extends EObject> Set<T> getReferringObjects(final @NonNull EObject eObject, final @NonNull Class<T> targetClass, final @NonNull EReference targetEReference) {
		checkArgument(eObject != null, ARG_OBJECT_MESSAGE);
		checkArgument(targetEReference != null, ARG_TARGET_REFERENCE_MESSAGE);
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		return getOrCreateAmaltheaAdapter(eObject).getNonNavigableInverseReferences(eObject)
				.stream()
				.filter(setting -> setting.getEStructuralFeature() == targetEReference)
				.map(Setting::getEObject)
				.filter(targetClass::isInstance)
				.map(targetClass::cast)
				.collect(Collectors.toSet());
	}

	public static IReferable getEObjectByID(final @NonNull Notifier context, final @Nullable String id) {
		checkArgument(context != null, ARG_NOTIFIER_MESSAGE);

		if (id == null || id.isEmpty()) return null;

		int beginIndex = id.contains("/") ? id.lastIndexOf('/') + 1 : 0;
		int endIndex = id.indexOf("?type=");
		if (endIndex > beginIndex) {
			String name = id.substring(beginIndex, endIndex);
			if (name.equals("no-name")) name = "";

			for (IReferable elem : getElements(context, name, IReferable.class)) {
				// first check the type because computation of unique name is more expensive
				if (id.endsWith(elem.eClass().getName()) && id.equals(elem.getUniqueName())) {
					return elem;
				}
			}
		}

		return null;
	}

	public static List<Set<IReferable>> getObjectsWithConflictingNames(final @NonNull Notifier context) {
		checkArgument(context != null, ARG_NOTIFIER_MESSAGE);

		// call index
		@NonNull List<@NonNull Set<@NonNull IReferable>> list = getOrCreateAmaltheaAdapter(context).getObjectsWithConflictingNames();

		// filter scope
		List<Set<IReferable>> result = new ArrayList<>();
		for (Set<IReferable> initialSet : list) {
			Set<IReferable> filteredSet = filterElements(context, initialSet);
			if (filteredSet.size() > 1) {
				result.add(filteredSet);
			}
		}

		return result;
	}

	/**
	 * Creates the index explicitly. If the index is already available the method will have no effect.
	 * <p>
	 * This method is optional. Normally the index will be built on demand.
	 *
	 * @param eObject
	 */
	public static void buildIndex(final @NonNull Notifier context) {
		checkArgument(context != null, ARG_NOTIFIER_MESSAGE);

		getOrCreateAmaltheaAdapter(context);
	}

	/**
	 * Deletes the object from its {@link EObject#eResource containing} resource
	 * and/or its {@link EObject#eContainer containing} object as well as from any
	 * other feature that references it within the enclosing root context
	 * (resource set, resource or root object). Contained children of the object
	 * are similarly removed from any features that reference them.
	 *
	 * @param eObject object to delete
	 */
	public static void delete(final @NonNull EObject eObject) {
		checkArgument(eObject != null, ARG_OBJECT_MESSAGE);

		ArrayList<EObject> list = new ArrayList<>();
		list.add(eObject);
		deleteAll(list, true);
	}


	/**
	 * Deletes the objects from their {@link EObject#eResource containing} resource
	 * and/or their {@link EObject#eContainer containing} object as well as from any
	 * other feature that references it within the enclosing root context
	 * (resource set, resource or root object). Contained children of the object
	 * are similarly removed from any features that reference them.
	 *
	 * @param eObjects objects to delete
	 */
	public static void deleteAll(final @NonNull Collection<? extends EObject> eObjects) {
		checkArgument(eObjects != null, ARG_COLLECTION_MESSAGE);

		deleteAll(eObjects, true);
	}


	/**
	 * Deletes the objects from their {@link EObject#eResource containing} resource
	 * and/or their {@link EObject#eContainer containing} object as well as from any
	 * other feature that references it within the enclosing root context
	 * (resource set, resource or root object).
	 * If recursive is true, contained children of the object are similarly removed
	 * from any features that reference them.
	 *
	 * @param eObjects objects to delete
	 * @param recursive true: contained children should also be deleted
	 */
	public static void deleteAll(final @NonNull Collection<? extends EObject> eObjects, boolean recursive) {
		checkArgument(eObjects != null, ARG_COLLECTION_MESSAGE);

		@SuppressWarnings("null")
		Set<@NonNull ? extends EObject> objectsToDelete = eObjects.stream()
				.filter(Objects::nonNull).collect(Collectors.toSet());

		// extended argument check: ensure a common context

		Notifier commonContext = ensureCommonContext(objectsToDelete);
		if (commonContext == null)
			return;

		// collect objects to delete

		Set<EObject> eAllObjects = new HashSet<>();
		if (recursive) {
			// add contained objects
			for (EObject eObject : objectsToDelete) {
				for (TreeIterator<EObject> j = eObject.eAllContents(); j.hasNext();) {
					InternalEObject childEObject = (InternalEObject) j.next();
					eAllObjects.add(childEObject);
				}
			}
		}
		// add original objects
		eAllObjects.addAll(objectsToDelete);

		// delete the objects

		final AmaltheaCrossReferenceAdapter amaltheaAdapter = getOrCreateAmaltheaAdapter(commonContext);
		for (final EObject eObject : eAllObjects) {
			final Collection<Setting> inverseReferences = amaltheaAdapter.getInverseReferences(eObject);
			for (final EStructuralFeature.Setting settingObject : inverseReferences) {
				if (settingObject.getEStructuralFeature().isChangeable()) {
					// remove the reference relation
					EcoreUtil.remove(settingObject, eObject);
				}
			}

			// remove the element
			EcoreUtil.remove(eObject);
		}
	}

	private static Notifier ensureCommonContext(Set<@NonNull ? extends EObject> objectsToDelete) {
		Notifier commonContext = null;
		for (final EObject eObject : objectsToDelete) {
			final Notifier context = getRootContext(eObject);
			if (commonContext == null) {
				commonContext = context;
			} else if (commonContext != context) {
				throw new IllegalArgumentException("Objects don't share a common context");
			}
		}
		return commonContext;
	}

	/**
	 * Finds elements by class
	 *
	 * @param context EObject, Resource or ResourceSet
	 * @param targetClass for example: <code>Label.class</code>
	 * @return Set of named objects (INamed)
	 */
	public static <T extends INamed> Set<T> getElements(final @NonNull Notifier context, final @NonNull Class<T> targetClass) {
		checkArgument(context != null, ARG_NOTIFIER_MESSAGE);
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		@NonNull Set<@NonNull T> elements = getOrCreateAmaltheaAdapter(context).getElements(targetClass);

		return filterElements(context, elements);
	}

	/**
	 * Finds elements by name and class
	 *
	 * @param context EObject, Resource or ResourceSet
	 * @param name String
	 * @param targetClass for example: <code>Label.class</code>
	 * @return Set of named objects (INamed)
	 */
	public static <T extends INamed> Set<T> getElements(final @NonNull Notifier context, final @NonNull String name,
			final @NonNull Class<T> targetClass) {
		checkArgument(context != null, ARG_NOTIFIER_MESSAGE);
		checkArgument(name != null, ARG_NAME_MESSAGE);
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		@NonNull Set<@NonNull T> elements = getOrCreateAmaltheaAdapter(context).getElements(name, targetClass);

		return filterElements(context, elements);
	}

	/**
	 * Finds elements by name pattern and class
	 *
	 * @param context EObject, Resource or ResourceSet
	 * @param namePattern for example: <code>Pattern.compile("Prefix_.*")</code>
	 * @param targetClass for example: <code>Label.class</code>
	 * @return Set of named objects (INamed)
	 */
	public static <T extends INamed> Set<T> getElements(final @NonNull Notifier context, final @NonNull Pattern namePattern,
			final @NonNull Class<T> targetClass) {
		checkArgument(context != null, ARG_NOTIFIER_MESSAGE);
		checkArgument(namePattern != null, ARG_PATTERN_MESSAGE);
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		@NonNull Set<@NonNull T> elements = getOrCreateAmaltheaAdapter(context).getElements(namePattern, targetClass);

		return filterElements(context, elements);
	}

	/**
	 * Dumps adapter info to a print stream
	 *
	 * @param context	EObject, Resource or ResourceSet
	 * @param info		content selector <ul>
	 * 					<li> 1 - basic adapter info (resources, size of maps)
	 * 					<li> 2 - cross reference map
	 * 					<li> 3 - name index </ul>
	 * @param stream	output stream (use System.out to print to console)
	 */
	public static void dumpAdapterInfo(final @NonNull Notifier context, int info, final @NonNull PrintStream stream) {
		checkArgument(context != null, ARG_NOTIFIER_MESSAGE);
		checkArgument(stream != null, ARG_STREAM_MESSAGE);

		AmaltheaCrossReferenceAdapter adapter = getOrCreateAmaltheaAdapter(context);

		switch (info) {
		case 1: adapter.dumpInfo(stream); break;
		case 2: adapter.dumpCrossReferenceMap(stream); break;
		case 3: adapter.dumpNameIndex(stream); break;
		default: stream.append("undefined info selector: " + info);
		}
	}

	private static synchronized @NonNull AmaltheaCrossReferenceAdapter getOrCreateAmaltheaAdapter(final @NonNull Notifier target) {
		// Try to get Amalthea adapter
		final EList<Adapter> adapters = getRootContext(target).eAdapters();
		for (final Adapter adapter : adapters) {
			if (adapter instanceof AmaltheaCrossReferenceAdapter) {
				return (AmaltheaCrossReferenceAdapter) adapter;
			}
		}

		// Create Amalthea adapter
		final AmaltheaCrossReferenceAdapter amaltheaAdapter = new AmaltheaCrossReferenceAdapter();
		adapters.add(amaltheaAdapter);
		return amaltheaAdapter;
	}

	/**
	 * Gets the root context of an EObject
	 */
	private static @NonNull Notifier getRootContext(final @NonNull EObject eObject) {
		final EObject rootContainer = EcoreUtil.getRootContainer(eObject);
		final Resource resource = rootContainer.eResource();
		if (resource != null) {
			return getRootContext(resource);
		}

		return rootContainer;
	}

	/**
	 * Gets the root context of a Resource
	 */
	private static @NonNull Notifier getRootContext(final @NonNull Resource resource) {
		final ResourceSet resourceSet = resource.getResourceSet();
		if (resourceSet != null) {
			return resourceSet;
		}

		return resource;
	}

	/**
	 * Gets the root context of a Notifier (EObject, Resource or Resource Set)
	 */
	private static @NonNull Notifier getRootContext(final @NonNull Notifier notifier) {
		if (notifier instanceof EObject) {
			return getRootContext((EObject) notifier);
		}
		else if (notifier instanceof Resource) {
			return getRootContext((Resource) notifier);
		}

		return notifier;
	}

	/**
	 * Gets the resource of a Notifier (EObject, Resource or Resource Set)
	 */
	private static Resource getResource(final Notifier notifier) {
		if (notifier instanceof EObject) {
			return((EObject) notifier).eResource();
		}
		else if (notifier instanceof Resource) {
			return (Resource) notifier;
		}

		return null;
	}

	/**
	 * Removes elements out of scope (to handle larger editing domains / resource sets)
	 */
	private static <T extends INamed> Set<T> filterElements(final @NonNull Notifier context, Set<@NonNull T> elements) {
		Notifier rootContext = getRootContext(context);
		Resource resource = getResource(context);
		if (rootContext instanceof ResourceSet && resource != null) {
			URI folderUri = resource.getURI().trimSegments(1);
			return elements.stream()
					.filter(e -> e.eResource().getURI().trimSegments(1).equals(folderUri))
					.collect(Collectors.toSet());
		}

		return elements;
	}

}
