/*******************************************************************************
 * Copyright (c) 2016, 2020 Chalmers | University of Gothenburg, rt-labs and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *   
 * SPDX-License-Identifier: EPL-2.0
 *   
 * Contributors:
 *     Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
 *     Chalmers | University of Gothenburg - additional features, updated API
 *     Fredrik Johansson and Themistoklis Ntoukolis - initial implementation of the Matrix View
 *******************************************************************************/
package org.eclipse.capra.ui.matrix.views;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import org.eclipse.capra.core.adapters.Connection;
import org.eclipse.capra.core.adapters.TraceMetaModelAdapter;
import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
import org.eclipse.capra.core.handlers.IArtifactHandler;
import org.eclipse.capra.core.handlers.IArtifactUnpacker;
import org.eclipse.capra.core.helpers.ArtifactHelper;
import org.eclipse.capra.core.helpers.EMFHelper;
import org.eclipse.capra.core.helpers.ExtensionPointHelper;
import org.eclipse.capra.core.helpers.TraceHelper;
import org.eclipse.capra.ui.helpers.SelectionSupportHelper;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixBodyToolTip;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixColumnHeaderDataProvider;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixDataProvider;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixHeaderToolTip;
import org.eclipse.capra.ui.matrix.TraceabilityMatrixRowHeaderDataProvider;
import org.eclipse.capra.ui.matrix.selection.TraceabilityMatrixSelectionProvider;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.AbstractUiBindingConfiguration;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.DefaultNatTableStyleConfiguration;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.export.command.ExportCommand;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hover.HoverLayer;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.resize.action.ColumnResizeCursorAction;
import org.eclipse.nebula.widgets.nattable.resize.action.RowResizeCursorAction;
import org.eclipse.nebula.widgets.nattable.resize.event.ColumnResizeEventMatcher;
import org.eclipse.nebula.widgets.nattable.resize.event.RowResizeEventMatcher;
import org.eclipse.nebula.widgets.nattable.resize.mode.ColumnResizeDragMode;
import org.eclipse.nebula.widgets.nattable.resize.mode.RowResizeDragMode;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.Style;
import org.eclipse.nebula.widgets.nattable.ui.action.IMouseAction;
import org.eclipse.nebula.widgets.nattable.ui.binding.UiBindingRegistry;
import org.eclipse.nebula.widgets.nattable.ui.matcher.MouseEventMatcher;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.ViewPart;

/**
 * Provides a traceability matrix view, i.e., a tabular view of how the
 * different artifacts are related.
 * <p>
 * The traceability matrix shows all selected artifacts and the artifacts they
 * are directly connected to via trace links. It also displays the type of link
 * between the artifacts, allows navigating to the artifact by double-clicking
 * the column header, and shows information about the artifact and the trace
 * link as a tool-tip. It is also possible to export the currently viewed
 * traceability matrix as a Microsoft Excel file.
 * <p>
 * The implementation uses NatTable.
 * 
 * @author Fredrik Johansson
 * @author Themistoklis Ntoukolis
 * @author Jan-Philipp Steghöfer
 *
 */
public class TraceabilityMatrixView extends ViewPart {

	/**
	 * The ID of the view as specified by the extension.
	 */
	public static final String ID = "org.eclipse.capra.ui.matrix.views.TraceabilityMatrixView";

	private static final String SAME_LABEL = "SAME"; // When column header and row header are the same
	private static final String LINK_LABEL = "LINKED"; // When there is a link between

	private NatTable traceMatrixTable;
	private Action refreshAction, showAllAction, exportExcelAction;
	private Composite parent;

	private ResourceSet resourceSet = new ResourceSetImpl();

	private final TraceMetaModelAdapter traceAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
	private TraceMetaModelAdapter metamodelAdapter = ExtensionPointHelper.getTraceMetamodelAdapter().get();
	private TracePersistenceAdapter persistenceAdapter = ExtensionPointHelper.getTracePersistenceAdapter().get();
	private EObject traceModel = null;
	private EObject artifactModel = null;
	private ArtifactHelper artifactHelper;
	private TraceHelper traceHelper;

	private TraceabilityMatrixDataProvider bodyDataProvider;
	private BodyLayerStack bodyLayer;

	private List<Object> selectedModels = new ArrayList<>();
	private boolean selectionModified = false;

	/**
	 * Listener to detect changes in the selection of other views. Redraws the table
	 * if necessary.
	 */
	private ISelectionListener selectionListener = new ISelectionListener() {
		@Override
		public void selectionChanged(IWorkbenchPart part, ISelection selection) {
			populateSelectedModels(part, selection);
			if (traceMatrixTable != null && selectionModified) {
				updateTraceabilityMatrix();
			}
		}
	};

	/**
	 * Color configuration. First changing the background color for the labels.
	 * After that is the coloring for hovering.
	 */
	private AbstractRegistryConfiguration capraNatTableStyleConfiguration = new AbstractRegistryConfiguration() {
		@Override
		public void configureRegistry(IConfigRegistry configRegistry) {
			// Black background for cells where there should not be any links
			Style cellStyle = new Style();
			cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_BLACK);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle, DisplayMode.NORMAL,
					SAME_LABEL);

			// Green background for cells where there is a link.
			cellStyle = new Style();
			cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_GREEN);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle, DisplayMode.NORMAL,
					LINK_LABEL);

			// Style that is applied when cells are hovered
			Style style = new Style();
			style.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_YELLOW);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, style, DisplayMode.HOVER);

			// Style that is applied when selected cells are hovered
			style = new Style();
			style.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, GUIHelper.COLOR_GREEN);
			configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, style, DisplayMode.SELECT_HOVER);
		}
	};

	/**
	 * Making it possible to resize columns and rows.
	 */
	private AbstractUiBindingConfiguration capraUiBindingConfiguration = new AbstractUiBindingConfiguration() {

		@Override
		public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
			uiBindingRegistry.registerFirstMouseMoveBinding(
					new ColumnResizeEventMatcher(SWT.NONE, GridRegion.ROW_HEADER, 0), new ColumnResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(
					new ColumnResizeEventMatcher(SWT.NONE, GridRegion.ROW_HEADER, 1), new ColumnResizeDragMode());
			uiBindingRegistry.registerFirstMouseMoveBinding(
					new RowResizeEventMatcher(SWT.NONE, GridRegion.COLUMN_HEADER, 0), new RowResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(
					new RowResizeEventMatcher(SWT.NONE, GridRegion.COLUMN_HEADER, 1), new RowResizeDragMode());
			// Make the corner on the top left also resizable
			uiBindingRegistry.registerFirstMouseMoveBinding(
					new ColumnResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 0), new ColumnResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(new ColumnResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 1),
					new ColumnResizeDragMode());
			uiBindingRegistry.registerFirstMouseMoveBinding(new RowResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 0),
					new RowResizeCursorAction());
			uiBindingRegistry.registerFirstMouseDragMode(new RowResizeEventMatcher(SWT.NONE, GridRegion.CORNER, 1),
					new RowResizeDragMode());
		}
	};

	/**
	 * Setting labels based on links and later use the labels for customized layout.
	 */
	private IConfigLabelAccumulator cellLabelAccumulator = new IConfigLabelAccumulator() {
		@Override
		public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
			int columnIndex = bodyLayer.getColumnIndexByPosition(columnPosition);
			int rowIndex = bodyLayer.getRowIndexByPosition(rowPosition);
			if (sameElement(bodyDataProvider.getRow(rowIndex), bodyDataProvider.getColumn(columnIndex))) {
				configLabels.addLabel(SAME_LABEL);
			} else {
				String cell_text = (String) bodyDataProvider.getDataValue(columnIndex, rowIndex);
				if (!cell_text.equals("")) {
					configLabels.addLabel(LINK_LABEL);
				}
			}
		}
	};

	@Override
	public void createPartControl(Composite parent) {
		this.parent = parent;
		updateTraceabilityMatrix();

		makeActions();
		contributeToActionBars();

		// Adding support to react to selections in other views
		getViewSite().getPage().addSelectionListener(selectionListener);

	}

	@Override
	public void dispose() {
		getViewSite().getPage().removeSelectionListener(selectionListener);
		traceMatrixTable.dispose();
		traceMatrixTable = null;
		super.dispose();
	}

	@Override
	public void setFocus() {
		if (traceMatrixTable != null) {
			traceMatrixTable.setFocus();
		}
	}

	/**
	 * Updates the traceability matrix with data from the current selection or with
	 * data from all traced artifacts if the selection is empty. In essence, it
	 * disposes of the current table and creates a new one with the current data.
	 * Also layouts the parent to make sure the table is displayed correctly.
	 */
	@SuppressWarnings("unchecked")
	protected void updateTraceabilityMatrix() {
		EObject selectedObject;
		List<Connection> traces = new ArrayList<>();

		this.artifactModel = persistenceAdapter.getArtifactWrappers(resourceSet);
		this.artifactHelper = new ArtifactHelper(this.artifactModel);
		this.traceModel = persistenceAdapter.getTraceModel(resourceSet);
		this.traceHelper = new TraceHelper(traceModel);

		if (!selectedModels.isEmpty()) {
			// Show the matrix for the selected objects
			for (Object model : selectedModels) {
				IArtifactHandler<Object> handler = (IArtifactHandler<Object>) this.artifactHelper.getHandler(model)
						.orElse(null);
				if (handler != null) {
					Object unpackedElement = null;
					if (handler instanceof IArtifactUnpacker) {
						unpackedElement = IArtifactUnpacker.class.cast(handler).unpack(model);
					} else {
						unpackedElement = model;
					}
					EObject wrappedElement = handler.createWrapper(unpackedElement, this.artifactModel);
					if (traceHelper.isArtifactInTraceModel(wrappedElement)) {
						selectedObject = wrappedElement;
						traces.addAll(this.traceAdapter.getConnectedElements(selectedObject, this.traceModel));
					}
				}
			}
		} else {
			// Without a selection, show a matrix of all traces
			if (traceModel != null) {
				traces = metamodelAdapter.getAllTraceLinks(traceModel);
			}
		}
		// If the current selection does not contain elements from the trace model, it
		// is possible that the list of traces is empty. By catching this case, we only
		// update the traceability matrix when there is actually something to show.
		if (!traces.isEmpty()) {
			if (traceMatrixTable != null) {
				traceMatrixTable.dispose();
				traceMatrixTable = null;
			}
			// Creating data providers for body, column and row. The data provider for the
			// body provides the data which will be shown in the cells. For columns and
			// rows, the labels are created.
			this.bodyDataProvider = new TraceabilityMatrixDataProvider(traces, this.traceModel, this.traceAdapter);
			IDataProvider colHeaderDataProvider = new TraceabilityMatrixColumnHeaderDataProvider(
					this.bodyDataProvider.getColumns(), artifactHelper);
			IDataProvider rowHeaderDataProvider = new TraceabilityMatrixRowHeaderDataProvider(
					this.bodyDataProvider.getRows(), artifactHelper);

			// Putting the data providers to their respective stacks
			this.bodyLayer = new BodyLayerStack(this.bodyDataProvider);
			ColumnHeaderLayerStack columnHeaderLayer = new ColumnHeaderLayerStack(colHeaderDataProvider);
			RowHeaderLayerStack rowHeaderLayer = new RowHeaderLayerStack(rowHeaderDataProvider);
			DefaultCornerDataProvider cornerDataProvider = new DefaultCornerDataProvider(colHeaderDataProvider,
					rowHeaderDataProvider);
			CornerLayer cornerLayer = new CornerLayer(new DataLayer(cornerDataProvider), rowHeaderLayer,
					columnHeaderLayer);

			// Adding the labels to the body (cells).
			bodyLayer.setConfigLabelAccumulator(cellLabelAccumulator);

			// Putting all the layers to the grid.
			GridLayer gridLayer = new GridLayer(this.bodyLayer, columnHeaderLayer, rowHeaderLayer, cornerLayer);
			gridLayer.addConfiguration(capraUiBindingConfiguration);

			// Creating the table
			traceMatrixTable = new NatTable(parent, gridLayer, false);

			// Adding Configuration to the table
			traceMatrixTable.addConfiguration(new DefaultNatTableStyleConfiguration());
			traceMatrixTable.addConfiguration(this.capraNatTableStyleConfiguration);
			traceMatrixTable.configure();

			// Attach the selection provider
			getSite().setSelectionProvider(
					new TraceabilityMatrixSelectionProvider(bodyLayer.getSelectionLayer(), bodyDataProvider));

			// Adding the tool tips
			attachToolTip();

			// Finally, make sure everything is in the right place.
			parent.layout();
		}
	}

	// ********************************************************************

	/**
	 * Populates the {@link #selectedModels} property with the objects included in
	 * the provided selection.
	 * 
	 * @param part      the workbench part whose selection provider is used
	 * @param selection the selection from which the elements are extracted
	 */
	private void populateSelectedModels(IWorkbenchPart part, ISelection selection) {
		List<Object> newSelectedObjects = SelectionSupportHelper.extractSelectedElements(selection, part);
		if (!listEqualsIgnoreOrder(selectedModels, newSelectedObjects)) {
			selectionModified = true;
			selectedModels.clear();
			selectedModels.addAll(newSelectedObjects);
		} else {
			selectionModified = false;
		}
	}

	/**
	 * Compares to lists ignoring order and duplicates.
	 * 
	 * @param <T>   the type of the two lists
	 * @param list1 the first list to compare
	 * @param list2 the second list to compare
	 * @return <code>true</code> if the lists are the same, <code>false</code>
	 *         otherwise
	 */
	private <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
		return new HashSet<>(list1).equals(new HashSet<>(list2));
	}

	/**
	 * Create the tool tip instances.
	 */
	private void attachToolTip() {
		new TraceabilityMatrixBodyToolTip(this.traceMatrixTable, this.bodyDataProvider, this.artifactHelper);
		new TraceabilityMatrixHeaderToolTip(this.traceMatrixTable, this.bodyDataProvider, this.artifactHelper);
	}

	/**
	 * Opens an editor for the provided {@code element} based on the URL stored in
	 * the artifact.
	 * 
	 * @param element the element for which an editor should be opened
	 * @throws PartInitException if the editor could not be initialised
	 */
	private void openEditor(EObject element) throws PartInitException {
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
		try {
			URI uri = new URI(artifactHelper.getArtifactLocation(element));
			IPath artifactPath = new Path(uri.getPath());
			artifactPath = artifactPath.removeFirstSegments(1);
			IFile artifactFile = ResourcesPlugin.getWorkspace().getRoot().getFile(artifactPath);
			IDE.openEditor(page, artifactFile);
		} catch (URISyntaxException e) {
		}
	}

	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(refreshAction);
		manager.add(showAllAction);
		manager.add(new Separator());
		manager.add(exportExcelAction);
	}

	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(refreshAction);
		manager.add(showAllAction);
	}

	private void makeActions() {
		refreshAction = new Action() {
			@Override
			public void run() {
				updateTraceabilityMatrix();
			}
		};
		refreshAction.setText("Refresh");
		refreshAction.setToolTipText("Refresh");

		showAllAction = new Action() {
			@Override
			public void run() {
				selectedModels.clear();
				updateTraceabilityMatrix();
			}
		};
		showAllAction.setText("Show all");
		showAllAction.setToolTipText("Show all");

		exportExcelAction = new Action() {
			@Override
			public void run() {
				ExportCommand cmd = new ExportCommand(traceMatrixTable.getConfigRegistry(),
						traceMatrixTable.getShell());
				traceMatrixTable.doCommand(cmd);
			}
		};
		exportExcelAction.setText("Export to Excel...");
		exportExcelAction.setToolTipText("Exports the currently shown traceability matrix as an Excel file.");

	}

	private boolean sameElement(EObject first, EObject second) {
		return EMFHelper.getIdentifier(first).equals(EMFHelper.getIdentifier(second));
	}

	/**
	 * Class for the column stack
	 */
	private class ColumnHeaderLayerStack extends AbstractLayerTransform {

		public ColumnHeaderLayerStack(IDataProvider dataProvider) {
			DataLayer dataLayer = new DataLayer(dataProvider);
			ColumnHeaderLayer colHeaderLayer = new ColumnHeaderLayer(dataLayer, TraceabilityMatrixView.this.bodyLayer,
					TraceabilityMatrixView.this.bodyLayer.getSelectionLayer());

			// Adding double click to the column header
			colHeaderLayer.addConfiguration(new AbstractUiBindingConfiguration() {

				@Override
				public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
					uiBindingRegistry.registerDoubleClickBinding(MouseEventMatcher.columnHeaderLeftClick(0),
							new IMouseAction() {

								@Override
								public void run(NatTable natTable, MouseEvent event) {
									try {
										int columnPosition = natTable.getColumnPositionByX(event.x);
										int columnIndex = natTable.getColumnIndexByPosition(columnPosition);
										EObject element = bodyDataProvider.getColumn(columnIndex);
										openEditor(element);
									} catch (PartInitException e) {
										// Deliberately do nothing.
									}
								}
							});
				}
			});

			setUnderlyingLayer(colHeaderLayer);
		}
	}

	/**
	 * Class for the row stack
	 */
	private class RowHeaderLayerStack extends AbstractLayerTransform {

		public RowHeaderLayerStack(IDataProvider dataProvider) {
			DataLayer dataLayer = new DataLayer(dataProvider, 50, 20);
			RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(dataLayer, TraceabilityMatrixView.this.bodyLayer,
					TraceabilityMatrixView.this.bodyLayer.getSelectionLayer());

			// Adding double click to the row header
			rowHeaderLayer.addConfiguration(new AbstractUiBindingConfiguration() {

				@Override
				public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
					uiBindingRegistry.registerDoubleClickBinding(MouseEventMatcher.rowHeaderLeftClick(0),
							new IMouseAction() {

								@Override
								public void run(NatTable natTable, MouseEvent event) {
									try {
										int rowPosition = natTable.getRowPositionByY(event.y);
										int rowIndex = natTable.getRowIndexByPosition(rowPosition);
										EObject element = bodyDataProvider.getRow(rowIndex);
										openEditor(element);
									} catch (PartInitException e) {
										// Deliberately do nothing.
									}
								}

							});
				}
			});
			setUnderlyingLayer(rowHeaderLayer);
		}
	}

	/**
	 * Class for the body stack
	 */
	private class BodyLayerStack extends AbstractLayerTransform {
		private SelectionLayer selectionLayer;

		public BodyLayerStack(IDataProvider dataProvider) {
			DataLayer bodyDataLayer = new DataLayer(dataProvider);
			HoverLayer bodyHoverLayer = new HoverLayer(bodyDataLayer);
			this.selectionLayer = new SelectionLayer(bodyHoverLayer);
			ViewportLayer viewportLayer = new ViewportLayer(this.selectionLayer);
			setUnderlyingLayer(viewportLayer);
		}

		public SelectionLayer getSelectionLayer() {
			return this.selectionLayer;
		}
	}
}
