/*********************************************************************************
 * Copyright (c) 2020-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.visualization.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang.ClassUtils;
import org.eclipse.app4mc.visualization.ui.registry.ModelVisualization;
import org.eclipse.app4mc.visualization.ui.registry.ModelVisualizationRegistry;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.di.extensions.Service;
import org.eclipse.e4.ui.di.PersistState;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.model.application.ui.menu.MDirectToolItem;
import org.eclipse.e4.ui.model.application.ui.menu.MToolBarElement;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;

@SuppressWarnings("restriction")
public class VisualizationPart {

	/**
	 * The ID that is used in the model fragment for this part.
	 */
	public static final String ID = "org.eclipse.app4mc.visualization.ui.partdescriptor.app4mcvisualizations";

	private static final String LAST_SELECTED_STATE = "LAST_SELECTED";

	@Inject
	@Service
	ModelVisualizationRegistry registry;

	/**
	 * The {@link IEclipseContext} of this part.
	 */
	@Inject
	IEclipseContext partContext;

	/**
	 * The parent {@link Composite} of this part.
	 */
	Composite parentComposite;

	/**
	 * The {@link Composite} on which the visualization is rendered.
	 */
	Composite visualizationComposite;

	/**
	 * The model type that should be visualized.
	 */
	List<Class<?>> activeTypes;

	/**
	 * The model elements that are used for the visualization.
	 */
	List<?> activeModelElements;

	/**
	 * The current active rendered visualization.
	 */
	ModelVisualization activeVisualization;

	/**
	 * The list of all available visualizations available for the current {@link #activeType}.
	 */
	List<ModelVisualization> availableModelVisualizations;

	/**
	 * The {@link IEclipseContext} that is created for the visualization rendering.
	 */
	IEclipseContext activeContext;

	/**
	 * <code>true</code> if the selection listener is disabled, <code>false</code>
	 * if the visualization is updated on selection changes.
	 */
	boolean pinned = false;

	/**
	 * Mapping of model type to visualization id to remember the last selected visualization.
	 */
	HashMap<String, String> lastSelected = new HashMap<>();

	private boolean adapterEnabled = true;
	/**
	 * EMF Adapter to reload the visualization on model property changes.
	 */
	Adapter updateViewAdapter = new AdapterImpl() {

		@Override
		public void notifyChanged(Notification msg) {
			if (adapterEnabled && activeVisualization != null) {
				showVisualization(activeVisualization.getId());
			}
		}
	};

	@PostConstruct
	public void postConstruct(Composite parent, MPart part,
			@Optional @Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
		parentComposite = parent;
		parentComposite.setLayout(new FillLayout());
		parentComposite.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));

		if (visualizationComposite == null) {
			visualizationComposite = new Composite(parent, SWT.NONE);
			visualizationComposite.setLayout(new FillLayout());
			if (selection != null) {
				handleSelection(selection);
			} else {
				showEmpty(visualizationComposite);
			}
		}

		// load previous selected states
		Map<String, String> state = part.getPersistedState();

		String lastSelectedString = state.get(LAST_SELECTED_STATE);
		if (lastSelectedString != null) {
			lastSelectedString = lastSelectedString.substring(1, lastSelectedString.length() - 1);
			String[] keyValues = lastSelectedString.split(",");
			for (String entry : keyValues) {
				String[] keyValue = entry.split("=");
				if (keyValue.length == 2) {
					lastSelected.put(keyValue[0], keyValue[1]);
				}
			}
		}

		// ensure the checked state of the pin tool item is reset
		for (MToolBarElement element : part.getToolbar().getChildren()) {
			if (element.getElementId().equals("org.eclipse.app4mc.visualization.ui.directtoolitem.pin")) {
				MDirectToolItem toolItem = (MDirectToolItem) element;
				toolItem.setSelected(pinned);
			}
		}
	}

	/**
	 * Disposes a current visualization and renders the visualization for the
	 * current active model element.
	 *
	 * @param visualizationId The ID of the visualization to show. Can be
	 *                        <code>null</code> which results in showing the first
	 *                        available visualization.
	 */
	public void showVisualization(String visualizationId) {
		showVisualization(visualizationId, false);
	}

	/**
	 * Disposes a current visualization and renders the visualization for the
	 * current active model element.
	 *
	 * @param visualizationId The ID of the visualization to show. Can be
	 *                        <code>null</code> which results in showing the first
	 *                        available visualization.
	 * @param reload          <code>true</code> if this method is called to reload a
	 *                        visualization, <code>false</code> if a new
	 *                        visualization should be opened.
	 */
	public void showVisualization(String visualizationId, boolean reload) {
		if (parentComposite == null || (!reload && isPinned())) {
			return;
		}

		// clear any current active visualization
		if (visualizationComposite != null) {
			if (activeContext != null && activeVisualization != null) {
				ContextInjectionFactory.invoke(activeVisualization, PreDestroy.class, activeContext, null);
				activeContext.dispose();
			}
			visualizationComposite.dispose();
		}

		// create a new Composite as parent for the visualization
		visualizationComposite = new Composite(parentComposite, SWT.NONE);
		visualizationComposite.setLayout(new FillLayout());

		// find the visualization for the current active model type and the given id
		availableModelVisualizations = registry.getVisualizations(activeTypes);
		if (!availableModelVisualizations.isEmpty()) {

			if (visualizationId != null) {
				activeVisualization = availableModelVisualizations.stream()
						.filter(mv -> mv.getId().equals(visualizationId))
						.findFirst()
						.orElse(null);

				// only handle if there is a visualization for the given id
				if (activeVisualization != null) {
					lastSelected.put(activeTypes.get(0).getName(), visualizationId);	// ???
				} else {
					// take the first returned available visualization
					activeVisualization = availableModelVisualizations.get(0);
				}
			} else {
				// take the first returned available visualization
				activeVisualization = availableModelVisualizations.get(0);
			}

			if (activeVisualization != null) {
				activeContext = partContext.createChild(activeTypes.get(0) + " Visualization");	// ???
				activeContext.set(Composite.class, visualizationComposite);

				activeContext.set(activeVisualization.getType(), activeModelElements.get(0));
				activeContext.set(List.class, activeModelElements);

				ContextInjectionFactory.invoke(activeVisualization.getVisualization(), PostConstruct.class, activeContext);
				parentComposite.layout(true);
			} else {
				showEmpty(visualizationComposite);
			}
		} else {
			showEmpty(visualizationComposite);
		}
	}

	@Inject
	@Optional
	void handleSelection(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
		if (!pinned) {

			// ensure that we are able to remove the adapter from a previous selection
			EObject previous = null;
			if (activeModelElements != null
					&& activeModelElements.size() == 1
					&& activeModelElements.get(0) instanceof EObject) {
				previous = (EObject) activeModelElements.get(0);
			}

			if (selection instanceof TreeSelection && !selection.isEmpty()) {
				TreeSelection s = (TreeSelection) selection;

				activeModelElements = s.toList();

				activeTypes = getNearestCommonTypes(activeModelElements);

				availableModelVisualizations = null;

				// remove the adapter from a previous selection
				if (previous != null) {
					adapterEnabled = false;
					previous.eAdapters().remove(updateViewAdapter);
				}

				if (!activeTypes.isEmpty() && activeModelElements.size() == 1
						&& activeModelElements.get(0) instanceof EObject) {
					((EObject) activeModelElements.get(0)).eAdapters().add(updateViewAdapter);
					adapterEnabled = true;
				}

				// check if there is a default visualization already configured
				showVisualization(!activeTypes.isEmpty() ? lastSelected.get(activeTypes.get(0).getName()) : null);	// ???
			}
		}
	}

	private List<Class<?>> getNearestCommonTypes(List<?> modelElements) {
		if (modelElements.isEmpty()) {
			return Collections.emptyList();
		}

		// get type candidate
		Class<? extends Object> class1 = modelElements.get(0).getClass();
		Class<?>[] interfaces = class1.getInterfaces();
		final Class<?> typeCandidate = interfaces.length > 0 ? interfaces[0] : class1;

		// one model element
		if (modelElements.size() == 1) {
			return Collections.singletonList(typeCandidate);
		}

		// multiple model elements

		boolean sameModelType = modelElements.stream().allMatch(element -> {
			Class<? extends Object> elementClass = element.getClass();
			Class<?>[] elementInterfaces = elementClass.getInterfaces();
			return elementInterfaces.length > 0 && elementInterfaces[0].equals(typeCandidate);
		});

		// all elements are of the same type
		if (sameModelType) {
			return Collections.singletonList(typeCandidate);
		}

		// compute common interfaces

		// for class1:
		//  - compute all interfaces
		//  - keep interfaces in the same package
		//  - keep EObject as common super interface
		@SuppressWarnings("unchecked")
		List<Class<?>> allInterfaces = ClassUtils.getAllInterfaces(class1);
		final String name = class1.getPackage().getName();
		final String prefix = (name.endsWith(".impl")) ? name.substring(0, name.length() - 5) : name;
		allInterfaces.removeIf( i -> ! (i.equals(EObject.class) || i.getPackage().getName().startsWith(prefix)) );
		// compute intersection with interfaces of other model elements
		for (int i = 1; i < modelElements.size(); i++) {
			allInterfaces.retainAll(ClassUtils.getAllInterfaces(modelElements.get(i).getClass()));
		}
		// remove super interfaces
		List<Class<?>> commonInterfaces = new ArrayList<>();
		for (Class<?> tmpInterface : allInterfaces) {
			List<Class<?>> otherInterfaces = new ArrayList<>(allInterfaces);
			otherInterfaces.remove(tmpInterface);
			if (otherInterfaces.stream().noneMatch(other -> tmpInterface.isAssignableFrom(other))) {
				commonInterfaces.add(tmpInterface);
			}
		}

		return commonInterfaces;
	}

	/**
	 *
	 * @param parent The parent {@link Composite}, should be the {@link #visualizationComposite}.
	 */
	private void showEmpty(Composite parent) {
		Label label = new Label(parent, SWT.NONE);
		if (hasActiveModelElement()) {
			StringBuilder sb = new StringBuilder("There is no visualization available for the active selection.");
			if (activeTypes.isEmpty()) {
				sb.append("\n\n - no common types detected - ");
			} else {
				sb.append("\n\ndetected ");
				sb.append((activeModelElements.size() == 1) ? "" : "common " );
				sb.append((activeTypes.size() == 1) ? "type:" : "types:" );
				activeTypes.forEach(t -> sb.append("\n - " + t.getSimpleName()));
			}
			label.setText(sb.toString());
		} else {
			label.setText("There is no active selection.");
		}
		parent.getParent().layout(true);
	}

	@PreDestroy
	public void preDestroy() {
		if (visualizationComposite != null) {
			visualizationComposite.dispose();
		}
		if (activeContext != null) {
			activeContext.dispose();
		}
	}

	/**
	 *
	 * @return The model type that should be visualized.
	 */
	public List<Class<?>> getActiveModelTypes() {
		return activeTypes;
	}

	/**
	 *
	 * @return The model elements that are used for the visualization.
	 */
	public List<?> getActiveModelElements() {
		return activeModelElements;
	}

	/**
	 *
	 * @return <code>true</code> if an active model element is set,
	 *         <code>false</code> if no active model element is available.
	 */
	public boolean hasActiveModelElement() {
		return activeModelElements != null && !activeModelElements.isEmpty();
	}

	/**
	 *
	 * @return The current active rendered visualization.
	 */
	public ModelVisualization getActiveVisualization() {
		return activeVisualization;
	}

	/**
	 *
	 * @return The list of all available visualizations available for the current
	 *         {@link #activeType}.
	 */
	public List<ModelVisualization> getAvailableModelVisualizations() {
		return availableModelVisualizations != null ? availableModelVisualizations : Collections.emptyList();
	}

	/**
	 *
	 * @return <code>true</code> if the selection listener is disabled,
	 *         <code>false</code> if the visualization is updated on
	 *         selection changes.
	 */
	public boolean isPinned() {
		return pinned;
	}

	/**
	 *
	 * @param pinned <code>true</code> if the selection listener should be disabled,
	 *               <code>false</code> if the visualization should be updated on
	 *               selection changes.
	 */
	public void setPinned(boolean pinned) {
		this.pinned = pinned;
	}

	/**
	 * Persist the local state.
	 *
	 * @param part The part to which this instance is connected.
	 */
	@PersistState
	public void persistState(MPart part) {
		Map<String, String> state = part.getPersistedState();
		state.put(LAST_SELECTED_STATE, lastSelected.toString());
	}

}
