/**
 ********************************************************************************
 * Copyright (c) 2018-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.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.jdt.annotation.NonNull;

public class AmaltheaCrossReferenceAdapter extends ECrossReferenceAdapter {
	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_STREAM_MESSAGE = "Stream argument is null, expected: PrintStream";

	private final Map<String, Set<INamed>> nameIndex = new HashMap<>();

	public @NonNull Set<@NonNull INamed> getElements(final @NonNull String name) {
		checkArgument(name != null, ARG_NAME_MESSAGE);

		return getElements(name, INamed.class);
	}

	@SuppressWarnings("null")
	public <T extends INamed> @NonNull Set<@NonNull T> getElements(final @NonNull String name, final @NonNull Class<T> targetClass) {
		checkArgument(name != null, ARG_NAME_MESSAGE);
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		final Set<T> result = new HashSet<>();
		final Set<INamed> values = nameIndex.get(name);
		if (values != null) {
			for (final INamed namedObject : values) {
				if (targetClass.isInstance(namedObject)) {
					result.add(targetClass.cast(namedObject));
				}
			}
		}
		return result;
	}

	public @NonNull Set<@NonNull INamed> getElements(final @NonNull Pattern namePattern) {
		checkArgument(namePattern != null, ARG_PATTERN_MESSAGE);

		return getElements(namePattern, INamed.class);
	}

	@SuppressWarnings("null")
	public <T extends INamed> @NonNull Set<@NonNull T> getElements(final @NonNull Pattern namePattern, final @NonNull Class<T> targetClass) {
		checkArgument(namePattern != null, ARG_PATTERN_MESSAGE);
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		final Set<T> result = new HashSet<>();
		for (final Map.Entry<String, Set<INamed>> entry : nameIndex.entrySet()) {
			if (namePattern.matcher(entry.getKey()).matches()) {
				for (final INamed namedObject : entry.getValue()) {
					if (targetClass.isInstance(namedObject)) {
						result.add(targetClass.cast(namedObject));
					}
				}
			}
		}
		return result;
	}

	@SuppressWarnings("null")
	public <T extends INamed> @NonNull Set<@NonNull T> getElements(final @NonNull Class<T> targetClass) {
		checkArgument(targetClass != null, ARG_CLASS_MESSAGE);

		final Set<T> result = new HashSet<>();
		for (final Map.Entry<String, Set<INamed>> entry : nameIndex.entrySet()) {
			for (final INamed namedObject : entry.getValue()) {
				if (targetClass.isInstance(namedObject)) {
					result.add(targetClass.cast(namedObject));
				}
			}
		}
		return result;
	}

	/**
	 * Returns sets of objects with the same type and same unique name
	 *
	 * @return Sets of objects
	 */
	@SuppressWarnings("null")
	public @NonNull List<@NonNull Set<@NonNull IReferable>> getObjectsWithConflictingNames() {
		final @NonNull List<@NonNull Set<@NonNull IReferable>> result = new ArrayList<>();

		for (Set<INamed> objects : nameIndex.values()) {
			if (objects.size() < 2) continue;

			Map<?, List<IReferable>> map1 = objects.stream()
				.filter(IReferable.class::isInstance)
				.map(IReferable.class::cast)
				.collect(Collectors.groupingBy(IReferable::getClass));

			for (List<IReferable> objectsWithSameType : map1.values()) {
				if (objectsWithSameType.size() < 2) continue;

				Map<String, List<IReferable>> map2 = objectsWithSameType.stream()
					.collect(Collectors.groupingBy(IReferable::getUniqueName));

				for (List<IReferable> objectsWithSameUniqueName : map2.values()) {
					if (objectsWithSameUniqueName.size() < 2) continue;

					result.add(new HashSet<>(objectsWithSameUniqueName));
				}
			}
		}

		return result;
	}

	@Override
	protected void selfAdapt(final Notification notification) {
		final Object notifier = notification.getNotifier();
		if (notifier instanceof INamed && notification.getFeature() == AmaltheaPackage.eINSTANCE.getINamed_Name()) {
			// Update the name index if an INamed's name is changed.
			final INamed namedObj = (INamed) notifier;

			int eventType = notification.getEventType();
			if (eventType == Notification.UNSET) {
				final String oldValue = notification.getOldStringValue();
				removeFromNameIndex(namedObj, oldValue);
			} else if (eventType == Notification.SET) {
				final String oldValue = notification.getOldStringValue();
				removeFromNameIndex(namedObj, oldValue);
				final String newValue = notification.getNewStringValue();
				addToNameIndex(namedObj, newValue);
			}
		} else {
			super.selfAdapt(notification);
		}
	}

	@Override
	protected void setTarget(final EObject target) {
		super.setTarget(target);

		if (target instanceof INamed) {
			// Add the INamed's name to the name index.
			final INamed namedObj = (INamed) target;
			addToNameIndex(namedObj, namedObj.getName());
		}
	}

	@Override
	protected void unsetTarget(final EObject target) {
		super.unsetTarget(target);

		if (target instanceof INamed) {
			// Remove the INamed's name to the name index.
			final INamed namedObj = (INamed) target;
			removeFromNameIndex(namedObj, namedObj.getName());
		}
	}

	private void addToNameIndex(final INamed eObject, final String name) {
		if (name != null) {
			Set<INamed> objSet = nameIndex.computeIfAbsent(name, k -> new HashSet<>());
			objSet.add(eObject);
		}
	}

	private void removeFromNameIndex(final INamed eObject, final String name) {
		if (name != null) {
			final Set<INamed> objSet = nameIndex.get(name);
			if (objSet != null) {
				objSet.remove(eObject);
				if (objSet.isEmpty()) {
					nameIndex.remove(name);
				}
			}
		}
	}

	/**
	 * Handles a containment change by adding and removing the adapter just like
	 * {@link EContentAdapter#handleContainment(Notification)}.
	 */
	@Override
	protected void handleContainment(final Notification notification) {
		switch (notification.getEventType()) {
		case Notification.RESOLVE:
			handleResolve(notification);
			break;
		case Notification.UNSET:
			handleUnset(notification);
			break;
		case Notification.SET:
			handleSet(notification);
			break;
		case Notification.ADD:
			handleAdd(notification);
			break;
		case Notification.ADD_MANY:
			handleAddMany(notification);
			break;
		case Notification.REMOVE:
			handleRemove(notification);
			break;
		case Notification.REMOVE_MANY:
			handleRemoveMany(notification);
			break;
		default:
			// no action required
		}
	}

	private void handleResolve(final Notification notification) {
		// We need to be careful that the proxy may be resolved while we are attaching this adapter.
		// We need to avoid attaching the adapter during the resolve
		// and also attaching it again as we walk the eContents() later.
		// Checking here avoids having to check during addAdapter.
		//
		final Notifier oldValue = (Notifier) notification.getOldValue();
		if (oldValue.eAdapters().contains(this)) {
			removeAdapter(oldValue);
			final Notifier newValue = (Notifier) notification.getNewValue();
			addAdapter(newValue);
		}
	}

	private void handleUnset(final Notification notification) {
		final Object oldValue = notification.getOldValue();
		if (oldValue != Boolean.TRUE && oldValue != Boolean.FALSE) {
			if (oldValue != null) {
				removeAdapter((Notifier) oldValue);
			}
			handleAdd(notification);
		}
	}

	private void handleSet(final Notification notification) {
		handleRemove(notification);
		handleAdd(notification);
	}

	private void handleAdd(final Notification notification) {
		final Notifier newValue = (Notifier) notification.getNewValue();
		if (newValue != null) {
			addAdapter(newValue);
		}
	}

	private void handleAddMany(final Notification notification) {
		@SuppressWarnings("unchecked")
		final Collection<Notifier> newValues = (Collection<Notifier>) notification.getNewValue();
		for (final Notifier newValue : newValues) {
			addAdapter(newValue);
		}
	}

	private void handleRemove(final Notification notification) {
		final Notifier oldValue = (Notifier) notification.getOldValue();
		if (oldValue != null) {
			removeAdapter(oldValue);
		}
	}

	private void handleRemoveMany(final Notification notification) {
		@SuppressWarnings("unchecked")
		final Collection<Notifier> oldValues = (Collection<Notifier>) notification.getOldValue();
		for (final Notifier oldContentValue : oldValues) {
			removeAdapter(oldContentValue);
		}
	}

	/**
	 * Dumps adapter info to a print stream
	 *
	 * @param stream	output stream (use System.out to print to console)
	 */
	public void dumpInfo(final @NonNull PrintStream stream) {
		checkArgument(stream != null, ARG_STREAM_MESSAGE);

		stream.println("Amalthea Cross Reference Adapter {");

		stream.println("  Id: " + this.getClass().getName() + '@' + Integer.toHexString(hashCode()));

		stream.print("  Resources: ");
		Set<Resource> resources = inverseCrossReferencer.keySet().stream()
			.map(EObject::eResource).filter(Objects::nonNull).collect(Collectors.toSet());
		if (resources.isEmpty()) {
			stream.println("[]");
		} else {
			stream.println("[");
			for (Resource resource : resources) {
				stream.println("    " + resource.getURI());
			}
			stream.println("  ]");
		}

		stream.println("  Cross Reference Map size: " + inverseCrossReferencer.size());
		stream.println("  Name Index size: " + nameIndex.size());
		stream.println('}');
	}

	/**
	 * Dumps cross reference map to a print stream
	 *
	 * @param stream	output stream (use System.out to print to console)
	 */
	public void dumpCrossReferenceMap(final @NonNull PrintStream stream) {
		checkArgument(stream != null, ARG_STREAM_MESSAGE);

		stream.println("Cross Reference Map (size: " + inverseCrossReferencer.size() + ") {");

		for (Map.Entry<EObject, Collection<EStructuralFeature.Setting>> entry : inverseCrossReferencer.entrySet()) {
			EObject eObject = entry.getKey();
			stream.print("  ");
			stream.print(description(eObject));
			stream.print(": ");

			Collection<EStructuralFeature.Setting> collection = entry.getValue();
			if (collection.isEmpty()) {
				stream.println("[]");
			} else {
				stream.println("[");
				for (Iterator<EStructuralFeature.Setting> j = collection.iterator(); j.hasNext();) {
					EStructuralFeature.Setting setting = j.next();

					EObject object = setting.getEObject();
					EStructuralFeature feature = setting.getEStructuralFeature();
					stream.print("    ");
					stream.print(feature.getName());
					stream.print(" <- ");
					stream.print(description(object));
					if (j.hasNext()) {
						stream.println(",");
					}
				}
				stream.println(']');
			}
		}

		stream.println('}');
	}

	/**
	 * Dumps name index to a print stream
	 *
	 * @param stream	output stream (use System.out to print to console)
	 */
	public void dumpNameIndex(final @NonNull PrintStream stream) {
		checkArgument(stream != null, ARG_STREAM_MESSAGE);

		stream.println("Name Index (size: " + nameIndex.size() + ") {");

		nameIndex.entrySet()
			.stream()
			.sorted(Map.Entry.<String, Set<INamed>>comparingByKey())
			.forEachOrdered(e -> {
				stream.print("  \"" + e.getKey() + "\": ");
				stream.println(e.getValue()
								.stream()
								.map(obj -> obj.eClass().getName())
								.sorted()
								.collect(Collectors.toList())
				);
			});

		stream.println('}');
	}

	private String description(EObject eObject) {
		StringBuilder result = new StringBuilder();
		result.append(eObject.eClass().getName());
		if (eObject instanceof INamed) {
			result.append(" \"" + ((INamed) eObject).getName() + "\"");
		}
		if (eObject.eContainer() instanceof INamed) {
			INamed cont = (INamed) eObject.eContainer();
			result.append(" (container: " + cont.eClass().getName() + " \"" + cont.getName() + "\")");
		}
		return result.toString();
	}

}
