/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.test.internal.performance.results.ui;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolTip;
import org.eclipse.test.internal.performance.results.db.AbstractResults;
import org.eclipse.test.internal.performance.results.db.BuildResults;
import org.eclipse.test.internal.performance.results.db.ConfigResults;
import org.eclipse.test.internal.performance.results.db.PerformanceResults;
import org.eclipse.test.internal.performance.results.db.ScenarioResults;
import org.eclipse.test.internal.performance.results.model.BuildResultsElement;
import org.eclipse.test.internal.performance.results.model.PerformanceResultsElement;
import org.eclipse.test.internal.performance.results.model.ResultsElement;
import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants;
import org.eclipse.test.internal.performance.results.utils.Util;


/**
 * Tab to display all performances results numbers for a configuration (i.e a performance machine).
 */
public class BuildsComparisonTab {

	// Colors
	static final Display DEFAULT_DISPLAY = Display.getDefault();
	static final Color BLUE= DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_BLUE);
	static final Color DARK_GREEN= DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_DARK_GREEN);
	static final Color GRAY = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_GRAY);
	static final Color MAGENTA = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_MAGENTA);
	static final Color RED = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_RED);

	// SWT resources
	Shell shell;
	Display display;
	Table table;
	private GC gc;
	private Color lightred;
	private Color lightyellow;
	private Color darkyellow;
	private Color blueref;
	private Font boldFont;
	private Font italicFont;
	private Font boldItalicFont;
	Map<Point, ToolTip> toolTips;

	// Information
	String componentName;
	double[][] allValues;
	double[][] allErrors;

	// Cells management
	Point tableOrigin, tableSize;
	int columnsCount, rowsCount;
	List<List<Object>> firstLine;

	// Eclipse preferences
	private IEclipsePreferences preferences;

/*
 * Default constructor.
 */
public BuildsComparisonTab(String name) {
    this.componentName = name;
	this.preferences = InstanceScope.INSTANCE.getNode(IPerformancesConstants.PLUGIN_ID);
}

/**
 * Creates the tab folder page.
 *
 * @param view The view on which to create the tab folder page
 * @return the new page for the tab folder
 */
Composite createTabFolderPage (BuildsComparisonView view) {
	// Cache the shell and display.
	this.shell = view.tabFolder.getShell();
	this.display = this.shell.getDisplay();

	// Remove old table if present
	boolean initResources = this.table == null;
	if (this.table != null) {
		disposeTable();
	}

	// Create the "children" table
	int style = SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION;
	this.table = new Table(view.tabFolder, style);
	this.table.setLinesVisible (true);
	this.table.setHeaderVisible (true);
	GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
	gridData.heightHint = 150;
	this.table.setLayoutData (gridData);
	this.gc = new GC(this.table);

	// Init resources
	if (initResources) initResources();

	// Add columns to the table
	TableColumn firstColumn = new TableColumn(this.table, SWT.CENTER);
	firstColumn.setText("");
	PerformanceResultsElement results = view.getResults();
	String [] configDescriptions = results.getConfigDescriptions();
	int length = configDescriptions.length;
	for (int i = 0; i < length; i++) {
		TableColumn column = new TableColumn(this.table, SWT.CENTER);
		column.setText(configDescriptions[i]);
	}

	// Add lines to the table
	this.toolTips = new HashMap<>();
	boolean fingerprints = this.preferences.getBoolean(IPerformancesConstants.PRE_FILTER_ADVANCED_SCENARIOS, IPerformancesConstants.DEFAULT_FILTER_ADVANCED_SCENARIOS);
	fillTable(results, view.currentBuild, view.referenceBuild, fingerprints);

	// Updated columns
	for (int i=0; i<=length; i++) {
		TableColumn column = this.table.getColumn(i);
		column.setWidth(i==0?120:100);
	}

	// Store table info
	this.columnsCount = length;

	// Listen to mouse track events to display the table cell corresponding tooltip.
	MouseTrackListener mouseTrackListener = new MouseTrackListener() {
		ToolTip currentTooltip;
		@Override
    public void mouseHover(MouseEvent e) {
			if (this.currentTooltip != null) {
				this.currentTooltip.setVisible(false);
				this.currentTooltip = null;
			}
			Point cellPosition = currentCellPosition(e.x, e.y);
			if (cellPosition != null) {
				ToolTip tooltip = BuildsComparisonTab.this.toolTips.get(cellPosition);
				if (tooltip != null) {
					Point location = BuildsComparisonTab.this.table.toDisplay(new Point(e.x, e.y));
					tooltip.setLocation(location);
					tooltip.setVisible(true);
					this.currentTooltip = tooltip;
				}
			}
		}
		@Override
    public void mouseEnter(MouseEvent e) {
		}
		@Override
    public void mouseExit(MouseEvent e) {
		}
	};
	this.table.addMouseTrackListener(mouseTrackListener);

	// Select the first line by default (as this is the current build)
	this.table.select(0);

	// Return the built composite
	return this.table;
}

/*
 * Create and store a tooltip with the given information and at the given position.
 */
void createToolTip(String toolTipText, String toolTipMessage, int toolTipStyle, Point position) {
	ToolTip toolTip = new ToolTip(this.table.getShell(), toolTipStyle);
	toolTip.setAutoHide(true);
	toolTip.setText(toolTipText);
	toolTip.setMessage(/*"("+col+","+row+") "+*/toolTipMessage);
	this.toolTips.put(position, toolTip);
}

/*
 * Get the current cell position (column, row) from a point position.
 */
Point currentCellPosition(int x, int y) {

	// Compute the origin of the visible area
	if (this.tableOrigin == null) {
		this.tableOrigin = new Point(0, this.table.getHeaderHeight());
	}

	// Increment width until over current y position
	int height= this.tableOrigin.y;
	int row = this.table.getTopIndex();
	while (row<this.rowsCount && height<y) {
		height += this.table.getItemHeight();
		row++;
	}
	if (height < y) {
		// return when position is over the last line
		return null;
	}
	row--;

	// Increment width until being over current x position
	int col = 0;
	TableItem tableItem = this.table.getItem(row);
	Rectangle bounds = tableItem.getBounds(col);
	while (col<this.columnsCount) {
		int max = bounds.x + bounds.width + this.table.getGridLineWidth();
		if (x <= max) break;
		if (col == this.columnsCount) {
			// return when position is over the last column
			return null;
		}
		col++;
		bounds = tableItem.getBounds(col);
	}

	// Return the found table cell position
	return new Point(col, row);
}

/*
 * Dispose all SWT resources.
 */
public void dispose() {
	if (this.boldFont != null) {
		this.boldFont.dispose();
	}
	if (this.italicFont != null) {
		this.italicFont.dispose();
	}
	if (this.boldItalicFont != null) {
		this.boldItalicFont.dispose();
	}
	if (this.darkyellow != null) {
		this.darkyellow.dispose();
	}
	if (this.lightyellow != null) {
		this.lightyellow.dispose();
	}
	if (this.lightred != null) {
		this.lightred.dispose();
	}
	if (this.blueref != null) {
		this.blueref.dispose();
	}
	disposeTable();
}

/*
 * Dispose all SWT controls associated with the table.
 */
private void disposeTable() {
	if (this.toolTips != null) {
		Iterator<Point> cells = this.toolTips.keySet().iterator();
		while (cells.hasNext()) {
			ToolTip toolTip = this.toolTips.get(cells.next());
			toolTip.dispose();
		}
	}
	this.table.dispose();
	this.tableOrigin = null;
	this.firstLine = null;
}

/*
 * Fill the lines of the tables.
 * Get all the information from the model which are returned in a list (lines) of lists (columns).
 */
private void fillTable(PerformanceResultsElement results, String currentBuild, String referenceBuild, boolean fingerprints) {

	// Get all the scenario for the component
	final PerformanceResults performanceResults = results.getPerformanceResults();
	List<AbstractResults> scenarios = performanceResults.getComponentScenarios(this.componentName);
	int size = scenarios.size();

	// Get thresholds
	int failurePref = this.preferences.getInt(IPerformancesConstants.PRE_COMPARISON_THRESHOLD_FAILURE, IPerformancesConstants.DEFAULT_COMPARISON_THRESHOLD_FAILURE);
	int errorPref = this.preferences.getInt(IPerformancesConstants.PRE_COMPARISON_THRESHOLD_ERROR, IPerformancesConstants.DEFAULT_COMPARISON_THRESHOLD_ERROR);
	int improvementPref = this.preferences.getInt(IPerformancesConstants.PRE_COMPARISON_THRESHOLD_IMPROVEMENT, IPerformancesConstants.DEFAULT_COMPARISON_THRESHOLD_IMPROVEMENT);
	final double failureThreshold = -failurePref / 100.0;
	final double errorThreshold = errorPref / 100.0;
	final double improvementThreshold = improvementPref / 100.0;

	// Build the map made of one line per scenario results
	final String[] configs = performanceResults.getConfigNames(true/*sort*/);
	for (int i=0; i<size; i++) {
		ScenarioResults scenarioResults = (ScenarioResults) scenarios.get(i);
		if (!scenarioResults.isValid()) continue;
		final boolean fingerprint = scenarioResults.hasSummary();
		if (!fingerprints || fingerprint) {

			// The first column is the scenario name
			String scenarioName = scenarioResults.getShortName();
			TableItem item = new TableItem (this.table, SWT.NONE);
			item.setText(scenarioName);

			// Bold font and blue ref background color if this is a fingerprint test
			Font italic;
			if (fingerprint) {
				item.setFont(0, this.boldFont);
				item.setBackground(this.blueref);
				italic = this.boldItalicFont;
			} else {
				italic = this.italicFont;
			}

			// Fill config columns
			int length = configs.length;
			for (int j=0; j<length; j++) {

				// See whether there's available numbers
				int col = j+1;
				final ConfigResults configResults = scenarioResults.getConfigResults(configs[j]);
				if (configResults == null || !configResults.isValid()) {
					item.setText(col, "Invalid");
					item.setForeground(col, GRAY);
					item.setFont(col, italic);
					continue;
				}
				final BuildResults buildResults = configResults.getBuildResults(currentBuild);
				if (buildResults == null) {
					item.setText(col, "Missing results");
					item.setForeground(col, GRAY);
					item.setFont(col, italic);
					continue;
				}
				final BuildResults referenceResults = configResults.getBuildResults(referenceBuild);
				if (referenceResults == null) {
					item.setText(col, "Missing ref");
					item.setForeground(col, GRAY);
					item.setFont(col, italic);
					continue;
				}

				// Get numbers and infos
				double[] values = configResults.getNumbers(buildResults, referenceResults);

				// Reset tooltip info
				String toolTipText = null;
				String toolTipMessage = null;
				int toolTipStyle = SWT.BALLOON;

				// Get values array
				final double buildValue = values[AbstractResults.BUILD_VALUE_INDEX];
				final double referenceValue = values[AbstractResults.BASELINE_VALUE_INDEX];
				final double delta = values[AbstractResults.DELTA_VALUE_INDEX];
				final double error = values[AbstractResults.DELTA_ERROR_INDEX];

				// Set text with delta value
				final StringBuilder address = new StringBuilder("http://fullmoon.ottawa.ibm.com/downloads/drops/");
				address.append(currentBuild);
				address.append("/performance/");
				address.append(configResults.getName());
				address.append('/');
				address.append(scenarioResults.getFileName());
				address.append(".html");
				StringBuilder buffer = new StringBuilder("<a href=\"");
				buffer.append(address);
				buffer.append("\">");
				final String itemText = Util.PERCENTAGE_FORMAT.format(delta);
				buffer.append(itemText);
				buffer.append("</a>");

				// Simple text
				item.setText(col, itemText);

				/* Link + Editor
				Link link = new Link(this.table, SWT.CENTER);
				link.setText(buffer.toString());
				link.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						Program.launch(address.toString());
					}
				});
				final TableEditor editor = new TableEditor(this.table);
				editor.grabHorizontal = editor.grabVertical = true;
				editor.verticalAlignment = SWT.CENTER;
				editor.horizontalAlignment = SWT.CENTER;
				editor.setEditor(link, item, col);
				*/

				// Compute the tooltip to display on the cell
				if (error > errorThreshold) {
					// error is over the threshold
					item.setForeground(col, this.darkyellow);
					toolTipText = "May be not reliable";
					toolTipMessage = "The error on this result is "+Util.PERCENTAGE_FORMAT.format(error)+", hence it may be not reliable";
					toolTipStyle |= SWT.ICON_WARNING;
				}
				if (delta < -0.1) {
					// delta < -10%: failure shown by an red-cross icon + text in red
					item.setImage(col, ResultsElement.ERROR_IMAGE);
				}
				if (delta < failureThreshold) {
					// negative delta over the threshold shown in red
					item.setForeground(col, RED);
				} else if (delta > improvementThreshold) {
					// positive delta over the threshold are shown in green
					item.setForeground(col, DARK_GREEN);
				}

				// Moderate the status if the build value or the difference is small
				if (buildValue < 100 || referenceValue < 100) {
					if (toolTipText == null) {
						toolTipText = "";
					} else {
						toolTipText += ", ";
					}
					toolTipText += "Small value";
					if (toolTipMessage == null) {
						toolTipMessage = "";
					} else {
						toolTipMessage += ".\n";
					}
					toolTipMessage += "This test has a small value ("+buildValue+"ms)";
					toolTipStyle |= SWT.ICON_WARNING;
					item.setImage(col, ResultsElement.WARN_IMAGE);
				}

				// Add information in tooltip when history shows big variation
				double deviation = configResults.getStatistics(Util.BASELINE_BUILD_PREFIXES)[3];
				if (deviation > 0.2) {
					// deviation is over 20% over the entire history
					if (toolTipText == null) {
						toolTipText = "";
					} else {
						toolTipText += ", ";
					}
					toolTipText += "History shows erratic values";
					if (toolTipMessage == null) {
						toolTipMessage = "";
					} else {
						toolTipMessage += ".\n";
					}
					toolTipMessage += "The results history shows that the variation of its delta is over 20% ("+Util.PERCENTAGE_FORMAT.format(deviation)+"), hence its result is surely not reliable";
					// set the text in italic
					item.setFont(col, italic);
					toolTipStyle |= SWT.ICON_INFORMATION;
				} else if (deviation > 0.1) { // moderate the status when the test
					// deviation is between 10% and 20% over the entire history
					if (toolTipText == null) {
						toolTipText = "";
					} else {
						toolTipText += ", ";
					}
					toolTipText += "History shows unstable values";
					if (toolTipMessage == null) {
						toolTipMessage = "";
					} else {
						toolTipMessage += ".\n";
					}
					toolTipMessage += "The results history shows that the variation of its delta is between 10% and 20% ("+Util.PERCENTAGE_FORMAT.format(deviation)+"), hence its result may not be really reliable";
					// set the text in italic
					item.setFont(col, italic);
					if (toolTipStyle == SWT.BALLOON && delta >= -0.1) {
						toolTipStyle |= SWT.ICON_INFORMATION;
					} else {
						// reduce icon severity from error to warning
						toolTipStyle |= SWT.ICON_WARNING;
					}
				}

				// Set tooltip
				if (toolTipText != null) {
					createToolTip(toolTipText, toolTipMessage, toolTipStyle, new Point(col, i));
				}
			}
		}
	}
	this.rowsCount = size;
}

protected Shell getShell() {
	return this.shell;
}

/*
 * The tab text is the full machine name.
 */
public String getTabText() {
	return Util.componentDisplayName(this.componentName);
}

/*
 * Init the SWT resources
 */
private void initResources() {
	// Fonts
	String fontDataName = this.gc.getFont().getFontData()[0].toString();
	FontData fdItalic = new FontData(fontDataName);
	fdItalic.setStyle(SWT.ITALIC);
	this.italicFont = new Font(this.display, fdItalic);
	FontData fdBold = new FontData(fontDataName);
	fdBold.setStyle(SWT.BOLD);
	this.boldFont = new Font(this.display, fdBold);
	FontData fdBoldItalic = new FontData(fontDataName);
	fdBoldItalic.setStyle(SWT.BOLD | SWT.ITALIC);
	this.boldItalicFont = new Font(this.display, fdBoldItalic);

	// Colors
	this.lightred = new Color(DEFAULT_DISPLAY, 220, 50, 50);
	this.lightyellow = new Color(DEFAULT_DISPLAY, 255, 255, 160);
	this.darkyellow = new Color(DEFAULT_DISPLAY, 160, 160, 0);
	this.blueref = new Color(DEFAULT_DISPLAY, 200, 200, 255);
}

/*
 * Select the line corresponding to the given build.
 */
void select(BuildResultsElement buildResultsElement) {
	int count = this.table.getItemCount();
	String buildName = buildResultsElement.getName();
	TableItem[] items = this.table.getItems();
	for (int i=0; i<count; i++) {
		if (items[i].getText().endsWith(buildName)) {
			this.table.deselect(this.table.getSelectionIndex());
			this.table.select(i);
			return;
		}
	}
}
}
