/*******************************************************************************
 * Copyright (c) 2003, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Lars Vogel <Lars.Vogel@gmail.com> - Bug 422040
 *******************************************************************************/
package org.eclipse.ui.internal.progress;

import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.jface.window.IShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.misc.StatusUtil;
import org.eclipse.ui.internal.util.BundleUtility;
import org.eclipse.ui.progress.IProgressConstants;
import org.eclipse.ui.views.IViewDescriptor;

/**
 * The ProgressUtil is a class that contains static utility methods used for the
 * progress API.
 */

public class ProgressManagerUtil {

	static class ProgressViewerComparator extends ViewerComparator {
		@Override
		@SuppressWarnings({ "rawtypes", "unchecked" })
		public int compare(Viewer testViewer, Object e1, Object e2) {
			return ((Comparable) e1).compareTo(e2);
		}

		@Override
		public void sort(final Viewer viewer, Object[] elements) {
			/*
			 * https://bugs.eclipse.org/371354
			 *
			 * This ordering is inherently unstable, since it relies on modifiable
			 * properties of the elements: E.g. the default implementation in JobTreeElement
			 * compares getDisplayString(), many of whose implementations use
			 * getPercentDone().
			 *
			 * JavaSE 7+'s TimSort introduced a breaking change: It now throws a new
			 * IllegalArgumentException for bad comparators. Workaround is to retry a few
			 * times.
			 */
			for (int retries = 3; retries > 0; retries--) {
				try {
					Arrays.sort(elements, (a, b) -> ProgressViewerComparator.this.compare(viewer, a, b));
					return; // success
				} catch (IllegalArgumentException e) {
					// retry
				}
			}

			// One last try that will log and throw TimSort's IAE if it happens:
			super.sort(viewer, elements);
		}
	}

	/**
	 * A constant used by the progress support to determine if an operation is too
	 * short to show progress.
	 */
	public static long SHORT_OPERATION_TIME = 250;

	static final QualifiedName KEEP_PROPERTY = IProgressConstants.KEEP_PROPERTY;

	static final QualifiedName KEEPONE_PROPERTY = IProgressConstants.KEEPONE_PROPERTY;

	static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];

	private static String ellipsis = ProgressMessages.ProgressFloatingWindow_EllipsisValue;

	/**
	 * Return a status for the exception.
	 *
	 * @param exception
	 * @return IStatus
	 */
	static IStatus exceptionStatus(Throwable exception) {
		return StatusUtil.newStatus(IStatus.ERROR, exception.getMessage() == null ? "" : exception.getMessage(), //$NON-NLS-1$
				exception);
	}

	/**
	 * Log the exception for debugging.
	 *
	 * @param exception
	 */
	static void logException(Throwable exception) {
		BundleUtility.log(PlatformUI.PLUGIN_ID, exception);
	}

	// /**
	// * Sets the label provider for the viewer.
	// *
	// * @param viewer
	// */
	// static void initLabelProvider(ProgressTreeViewer viewer) {
	// viewer.setLabelProvider(new ProgressLabelProvider());
	// }
	/**
	 * Return a viewer comparator for looking at the jobs.
	 *
	 * @return ViewerComparator
	 */
	static ViewerComparator getProgressViewerComparator() {
		return new ProgressViewerComparator();
	}

	/**
	 * Open the progress view in the supplied window.
	 *
	 * @param window
	 */
	static void openProgressView(IWorkbenchWindow window) {
		IWorkbenchPage page = window.getActivePage();
		if (page == null) {
			return;
		}
		try {
			IViewDescriptor reference = WorkbenchPlugin.getDefault().getViewRegistry()
					.find(IProgressConstants.PROGRESS_VIEW_ID);

			if (reference == null) {
				return;
			}
			page.showView(IProgressConstants.PROGRESS_VIEW_ID);
		} catch (PartInitException exception) {
			logException(exception);
		}
	}

	/**
	 * Shorten the given text <code>t</code> so that its length doesn't exceed the
	 * given width. The default implementation replaces characters in the center of
	 * the original string with an ellipsis ("..."). Override if you need a
	 * different strategy.
	 *
	 * @param textValue
	 * @param control
	 * @return String
	 */
	static String shortenText(String textValue, Control control) {
		if (textValue == null) {
			return null;
		}
		int maxWidth = control.getBounds().width - 5;
		String ellipsisString = ellipsis;
		GC gc = new GC(control);
		try {
			return clipToSize(gc, textValue, ellipsisString, maxWidth);
		} finally {
			gc.dispose();
		}
	}

	private static String clipToSize(GC gc, String textValue, String ellipsisString, int maxWidth) {
		int averageCharWidth = (int) gc.getFontMetrics().getAverageCharacterWidth();
		int length = textValue.length();

		int secondWord = findSecondWhitespace(textValue, gc, maxWidth);
		int pivot = ((length - secondWord) / 2) + secondWord;

		int currentLength;
		int upperBoundWidth;
		int upperBoundLength = 0;

		// Now use newton's method to search for the correct string size
		int lowerBoundLength = 0;
		int lowerBoundWidth = 0;

		// Try to guess the size of the string based on the font's average
		// character width
		int estimatedCharactersThatWillFit = maxWidth / averageCharWidth;

		if (estimatedCharactersThatWillFit >= length) {
			int maxExtent = gc.textExtent(textValue).x;
			if (maxExtent <= maxWidth) {
				return textValue;
			}
			currentLength = Math.max(0, Math.round(length * ((float) maxWidth / maxExtent)) - ellipsisString.length());
			upperBoundWidth = maxExtent;
			upperBoundLength = length;
		} else {
			currentLength = Math.min(length, Math.max(0, estimatedCharactersThatWillFit - ellipsisString.length()));
			for (;;) {
				String s = clipToLength(textValue, ellipsisString, pivot, currentLength);
				int currentExtent = gc.textExtent(s).x;
				if (currentExtent > maxWidth) {
					upperBoundWidth = currentExtent;
					upperBoundLength = currentLength;
					break;
				}
				if (currentLength == length) {
					// No need to clip the string if the whole thing fits.
					return textValue;
				}
				lowerBoundWidth = currentExtent;
				lowerBoundLength = currentLength;
				currentLength = Math.min(length, currentLength * 2 + 1);
			}
		}

		String s;
		for (;;) {
			int oldLength = currentLength;
			s = clipToLength(textValue, ellipsisString, pivot, currentLength);

			int l = gc.textExtent(s).x;
			int tooBigBy = l - maxWidth;
			if (tooBigBy == 0) {
				// If this was exactly the right size, stop the binary
				// search
				break;
			} else if (tooBigBy > 0) {
				// The string is too big. Need to clip more.
				upperBoundLength = currentLength;
				upperBoundWidth = l;
				if (currentLength <= lowerBoundLength + 1) {
					// We're one character away from a value that is known
					// to clip too much, so opt for clipping slightly too
					// much
					currentLength = lowerBoundLength;
					break;
				}
				if (tooBigBy <= averageCharWidth * 2) {
					currentLength--;
				} else {
					int spaceToRightOfLowerBound = maxWidth - lowerBoundWidth;
					currentLength = lowerBoundLength
							+ (currentLength - lowerBoundLength) * spaceToRightOfLowerBound / (l - lowerBoundWidth);
					if (currentLength >= oldLength) {
						currentLength = oldLength - 1;
					} else if (currentLength <= lowerBoundLength) {
						currentLength = lowerBoundLength + 1;
					}
				}
			} else {
				// The string is too small. Need to clip less.
				lowerBoundLength = currentLength;
				lowerBoundWidth = l;
				if (currentLength >= upperBoundLength - 1) {
					// We're one character away from a value that is known
					// to clip too little, so opt for clipping slightly
					// too much
					currentLength = upperBoundLength - 1;
					break;
				}
				if (-tooBigBy <= averageCharWidth * 2) {
					currentLength++;
				} else {
					currentLength = currentLength
							+ (upperBoundLength - currentLength) * (-tooBigBy) / (upperBoundWidth - l);
					if (currentLength <= oldLength) {
						currentLength = oldLength + 1;
					} else if (currentLength >= upperBoundLength) {
						currentLength = upperBoundLength - 1;
					}
				}
			}
		}

		return clipToLength(textValue, ellipsisString, pivot, currentLength);
	}

	private static String clipToLength(String textValue, String ellipsisString, int pivot, int newLength) {
		return getClippedString(textValue, ellipsisString, pivot, textValue.length() - newLength);
	}

	private static String getClippedString(String textValue, String ellipsisString, int pivot, int charsToClip) {
		int length = textValue.length();
		if (charsToClip <= 0) {
			return textValue;
		}
		if (charsToClip >= length) {
			return ""; //$NON-NLS-1$
		}
		int start = pivot - charsToClip / 2;
		int end = pivot + (charsToClip + 1) / 2;

		if (start < 0) {
			end -= start;
			start = 0;
		}
		if (end < 0) {
			start -= end;
			end = 0;
		}

		String s1 = textValue.substring(0, start);
		String s2;
		if (end < length) {
			s2 = textValue.substring(end, length);
		} else {
			s2 = ""; //$NON-NLS-1$
		}
		return s1 + ellipsisString + s2;
	}

	/**
	 * Find the second index of a whitespace. Return the first index if there isn't
	 * one or 0 if there is no space at all.
	 *
	 * @param textValue
	 * @param gc        The GC to test max length
	 * @param maxWidth  The maximim extent
	 * @return int
	 */
	private static int findSecondWhitespace(String textValue, GC gc, int maxWidth) {
		int firstCharacter = 0;
		char[] chars = textValue.toCharArray();
		// Find the first whitespace
		for (int i = 0; i < chars.length; i++) {
			if (Character.isWhitespace(chars[i])) {
				firstCharacter = i;
				break;
			}
		}
		// If we didn't find it once don't continue
		if (firstCharacter == 0) {
			return 0;
		}
		// Initialize to firstCharacter in case there is no more whitespace
		int secondCharacter = firstCharacter;
		// Find the second whitespace
		for (int i = firstCharacter; i < chars.length; i++) {
			if (Character.isWhitespace(chars[i])) {
				secondCharacter = i;
				break;
			}
		}
		// Check that we haven't gone over max width. Throw
		// out an index that is too high
		if (gc.textExtent(textValue.substring(0, secondCharacter)).x > maxWidth) {
			if (gc.textExtent(textValue.substring(0, firstCharacter)).x > maxWidth) {
				return 0;
			}
			return firstCharacter;
		}
		return secondCharacter;
	}

	/**
	 * If there are any modal shells open reschedule openJob to wait until they are
	 * closed. Return true if it rescheduled, false if there is nothing blocking it.
	 *
	 * @param openJob the job to reschedule (with delay) when modal dialog is open
	 * @return boolean. true if the job was rescheduled due to modal dialogs.
	 */
	public static boolean rescheduleIfModalShellOpen(Job openJob) {
		Shell modal = getModalShellExcluding(null);
		if (modal == null) {
			return false;
		}

		// try again in a few seconds
		openJob.schedule(PlatformUI.getWorkbench().getProgressService().getLongOperationTime());
		return true;
	}

	/**
	 * Return whether or not it is safe to open this dialog. If so then return
	 * <code>true</code>. If not then set it to open itself when it has had
	 * ProgressManager#longOperationTime worth of ticks.
	 *
	 * @param dialog        ProgressMonitorJobsDialog that will be opening
	 * @param excludedShell The shell
	 * @return boolean. <code>true</code> if it can open. Otherwise return false and
	 *         set the dialog to tick.
	 */
	public static boolean safeToOpen(ProgressMonitorJobsDialog dialog, Shell excludedShell) {
		Shell modal = getModalShellExcluding(excludedShell);
		if (modal == null) {
			return true;
		}

		dialog.watchTicks();
		return false;
	}

	/**
	 * Return the modal shell that is currently open. If there isn't one then return
	 * null. If there are stacked modal shells, return the top one.
	 *
	 * @param shell A shell to exclude from the search. May be <code>null</code>.
	 *
	 * @return Shell or <code>null</code>.
	 */

	public static Shell getModalShellExcluding(Shell shell) {

		// If shell is null or disposed, then look through all shells
		if (shell == null || shell.isDisposed()) {
			Display display = PlatformUI.getWorkbench().getDisplay();
			if (display.isDisposed()) {
				return null;
			}
			return getModalChildExcluding(display.getShells(), shell);
		}

		// Start with the shell to exclude and check it's shells
		return getModalChildExcluding(shell.getShells(), shell);
	}

	/**
	 * Return the modal shell that is currently open. If there isn't one then return
	 * null.
	 *
	 * @param toSearch  shells to search for modal children
	 * @param toExclude shell to ignore
	 * @return the most specific modal child, or null if none
	 */
	private static Shell getModalChildExcluding(Shell[] toSearch, Shell toExclude) {
		int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;

		// Make sure we don't pick a parent that has a modal child (this can
		// lock the app)
		// If we picked a parent with a modal child, use the modal child instead

		for (int i = toSearch.length - 1; i >= 0; i--) {
			Shell shell = toSearch[i];
			if (shell.equals(toExclude) || shell.isDisposed()) {
				continue;
			}

			// Check if this shell has a modal child
			Shell[] children = shell.getShells();
			Shell modalChild = getModalChildExcluding(children, toExclude);
			if (modalChild != null) {
				return modalChild;
			}

			// If not, check if this shell is modal itself
			if (shell.isVisible() && (shell.getStyle() & modal) != 0) {
				return shell;
			}
		}

		return null;
	}

	/**
	 * Utility method to get the best parenting possible for a dialog. If there is a
	 * modal shell return it so as to avoid two modal dialogs. If not then return
	 * the shell of the active workbench window. If that shell is <code>null</code>
	 * or not visible, then return the splash shell if still visible. Otherwise
	 * return the shell of the active workbench window.
	 *
	 * @return the best parent shell or <code>null</code>
	 */
	public static Shell getDefaultParent() {
		Shell modal = getModalShellExcluding(null);
		if (modal != null) {
			return modal;
		}

		Shell nonModalShell = getNonModalShell();
		if (nonModalShell != null && nonModalShell.isVisible())
			return nonModalShell;

		try {
			Shell splashShell = WorkbenchPlugin.getSplashShell(PlatformUI.getWorkbench().getDisplay());
			if (splashShell != null && splashShell.isVisible()) {
				return splashShell;
			}
		} catch (IllegalAccessException | InvocationTargetException e) {
			// Use non-modal shell
		}

		return nonModalShell;
	}

	/**
	 * Get the active non modal shell. If there isn't one return null.
	 *
	 * @return Shell
	 */
	public static Shell getNonModalShell() {
		MApplication application = PlatformUI.getWorkbench().getService(MApplication.class);
		if (application == null) {
			// better safe than sorry
			return null;
		}
		MWindow window = application.getSelectedElement();
		if (window != null) {
			Object widget = window.getWidget();
			if (widget instanceof Shell) {
				return (Shell) widget;
			}
		}
		for (MWindow child : application.getChildren()) {
			Object widget = child.getWidget();
			if (widget instanceof Shell) {
				return (Shell) widget;
			}
		}
		return null;
	}


	/**
	 * Get the shell provider to use in the progress support dialogs. This provider
	 * will try to always parent off of an existing modal shell. If there isn't one
	 * it will use the current workbench window.
	 *
	 * @return IShellProvider
	 */
	static IShellProvider getShellProvider() {
		return ProgressManagerUtil::getDefaultParent;
	}

	/**
	 * Get the icons root for the progress support.
	 *
	 * @return URL
	 */
	public static URL getIconsRoot() {
		return BundleUtility.find(PlatformUI.PLUGIN_ID, ProgressManager.PROGRESS_FOLDER);
	}

	/**
	 * Return the location of the progress spinner.
	 *
	 * @return URL or <code>null</code> if it cannot be found
	 */
	public static URL getProgressSpinnerLocation() {
		try {
			return new URL(getIconsRoot(), "progress_spinner.png");//$NON-NLS-1$
		} catch (MalformedURLException e) {
			return null;
		}
	}
}
