/*****************************************************************************
 * Copyright (c) 2013, 2017 CEA LIST.
 *
 * All rights reserved. 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:
 *   CEA LIST - Initial API and implementation
 *****************************************************************************/
package org.eclipse.papyrus.cdo.internal.ui.util;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

import org.eclipse.gmf.runtime.common.ui.util.DisplayUtils;
import org.eclipse.papyrus.cdo.internal.ui.Activator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;

/**
 * This is the UIUtil type. Enjoy.
 */
public class UIUtil {

	/**
	 * Not instantiable by clients.
	 */
	private UIUtil() {
		super();
	}

	public static Executor uiSafeExecutor() {
		return UISafeExecutor.INSTANCE;
	}

	/**
	 * Posts a runnable to run later on the UI thread, whether the current
	 * thread is the UI or not. In fact, the name "later" suggests that usually
	 * this method is useful in code that is on the UI thread but needs to
	 * ensure that some block runs later, after other events have been
	 * processed.
	 *
	 * @param runnable
	 *            a block of code to run later
	 */
	public static void later(Runnable runnable) {
		DisplayUtils.getDisplay().asyncExec(runnable);
	}

	/**
	 * Posts a callable that needs access to the UI to run asynchronously on the
	 * specified {@code display} thread.
	 *
	 * @param display
	 *            the display on which to post a computation asynchronously
	 * @param callable
	 *            a computation to run asynchronously on the UI thread
	 * @return the future result of the {@code callable}
	 */
	public static <T> Future<T> asyncCall(Display display, Callable<T> callable) {
		final FutureTask<T> result = new FutureTask<T>(callable);
		display.asyncExec(result);
		return result;
	}

	/**
	 * A UI-safe execution of a {@code callable} that needs access to the UI. If
	 * the current thread is the UI thread, then the result will be available
	 * immediately. Otherwise, the {@code callable} will be invoked
	 * asynchronously and the result will be available some time later.
	 *
	 * @param callable
	 *            a computation to run on the UI thread
	 * @return the future result of the {@code callable}
	 */
	public static <T> Future<T> call(Callable<T> callable) {
		final FutureTask<T> result = new FutureTask<T>(callable);

		Display display = Display.getCurrent();
		if (display != null) {
			result.run();
		} else {
			DisplayUtils.getDisplay().asyncExec(result);
		}

		return result;
	}

	/**
	 * <p>
	 * Queries whether the current thread is the UI thread and, if not, posts an runnable to re-dispatch the calling method asynchronously on the UI thread.
	 * </p>
	 * <p>
	 * The intended usage pattern is thus:
	 * </p>
	 *
	 * <pre>
	 *     public void doSomethingToTheUI(Object arg1, String arg2) {
	 *         if (UIUtil.ensureUIThread(this, arg1, arg2) {
	 *             // do stuff here with arg1 and arg2 that requires
	 *             // the UI thread
	 *         }
	 *     }
	 * </pre>
	 *
	 * @param receiver
	 *            the receiver of the method to be (potentially) re-dispatched.
	 *            This is the object calling the {@code ensureUIThread()} utility
	 * @param arguments
	 *            the arguments passed in the method invocation to be
	 *            re-dispatched
	 *
	 * @return {@code true} if the current thread is the UI thread and the
	 *         calling method may proceed; {@code false} if the method
	 *         invocation was re-dispatched asynchronously and the calling
	 *         method must not proceed
	 */
	public static boolean ensureUIThread(final Object receiver,
			final Object... arguments) {

		final Display display = DisplayUtils.getDisplay();
		boolean result = Display.getCurrent() == display;

		if (!result) {
			// find the calling method and post its invocation asynchronously
			String callingMethodName = null;
			StackTraceElement[] stack = Thread.currentThread().getStackTrace();
			for (int i = 0; i < stack.length; i++) {
				StackTraceElement next = stack[i];
				if (UIUtil.class.getName().equals(next.getClassName())
						&& "ensureUIThread".equals(next.getMethodName())) { //$NON-NLS-1$

					callingMethodName = stack[i + 1].getMethodName();
					break;
				}
			}

			if (callingMethodName == null) {
				throw new IllegalStateException("Invalid stack trace"); //$NON-NLS-1$
			}

			final Method method = findMethod(receiver.getClass(),
					callingMethodName, arguments);
			if (method == null) {
				throw new IllegalStateException("Could not find calling method"); //$NON-NLS-1$
			}

			method.setAccessible(true);

			display.asyncExec(new Runnable() {

				@Override
				public void run() {
					try {
						method.invoke(receiver, arguments);
					} catch (Exception e) {
						Activator.log.error(e);
					}
				}
			});
		}

		return result;
	}

	private static Method findMethod(Class<?> owner, String name,
			Object[] arguments) {
		Method result = null;

		Class<?>[] actual = new Class<?>[arguments.length];
		for (int i = 0; i < arguments.length; i++) {
			actual[i] = (arguments[i] == null)
					? null
					: arguments[i].getClass();
		}

		Method[] declared = owner.getDeclaredMethods();
		out: for (int i = 0; i < declared.length; i++) {
			Method next = declared[i];
			if (name.equals(next.getName())) {
				Class<?>[] parameters = next.getParameterTypes();

				for (int j = 0; j < parameters.length; j++) {
					if ((actual[j] != null)
							&& !parameters[j].isAssignableFrom(actual[j])) {
						continue out;
					}
				}

				result = next;
				break out;
			}
		}

		return result;
	}

	//
	// Nested types
	//

	private static final class UISafeExecutor
			implements Executor {

		static final UISafeExecutor INSTANCE = new UISafeExecutor();

		@Override
		public void execute(Runnable command) {
			Display workbenchDisplay = PlatformUI.getWorkbench().getDisplay();
			if (Display.getCurrent() == workbenchDisplay) {
				command.run();
			} else {
				workbenchDisplay.asyncExec(command);
			}
		}
	}
}
