/*******************************************************************************
 * Copyright (c) 2009, 2019 Xored Software Inc 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
 * https://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     Xored Software Inc - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.rcptt.ecl.interop.internal.commands;

import static org.eclipse.rcptt.ecl.interop.internal.EclInteropPlugin.error;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.rcptt.ecl.core.Command;
import org.eclipse.rcptt.ecl.interop.Invoke;
import org.eclipse.rcptt.ecl.interop.InvokeUi;
import org.eclipse.rcptt.ecl.runtime.ICommandService;
import org.eclipse.rcptt.ecl.runtime.IPipe;
import org.eclipse.rcptt.ecl.runtime.IProcess;
import org.eclipse.rcptt.util.DisplayUtils;
import org.eclipse.rcptt.util.DisplayUtilsProvider;

public class InvokeService implements ICommandService {

	private static final Object NOT_CONVERTIBLE = new Object();

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public IStatus service(Command command, IProcess context) throws CoreException {

		final Invoke cmd = (Invoke) command;

		final Object object = cmd.getObject();
		if (object == null)
			return error("Null invocation target.");

		final Class class_ = object.getClass();
		final String name = cmd.getName();
		if (name == null || name.length() == 0)
			return error("Empty method name.");

		final Object[] args = cmd.getArgs().toArray();

		// --

		if (class_.isArray())
			return processArrayMethod(object, name, args, context.getOutput());

		// --

		Object result = null;
		try {
			final Method method = matchMethod(class_, name, args);
			if (method == null) {
				if (args.length > 0) {
					return error("Method not found.");
				}
				result = getFieldValue(class_, object, name);
			} else {
				DisplayUtils utils = DisplayUtilsProvider.getDisplayUtils();
				if (utils.isWidget(object) || cmd instanceof InvokeUi) {

					// no reason to go into generics here, everything is just
					// Object
					RunnableFuture future = new FutureTask(new Callable() {
						public Object call() throws Exception {
							return method.invoke(object, args);
						}
					});

					if (cmd.isNoResult() || method.getReturnType() == Void.TYPE) {
						utils.asyncExec(object, future);
						result = Status.OK_STATUS;
					} else {
						utils.syncExec(object, future);
						result = future.get();
					}
				} else
					result = method.invoke(object, args);
			}

		} catch (Exception e) {
			return error(e, "%s: %s", e.getClass().getName(), e.getMessage());
		}

		if (result != null)
			context.getOutput().write(result);
		return Status.OK_STATUS;
	}

	private static Object getFieldValue(Class<?> class_, Object object, String name) throws CoreException {
		if (class_ == null) {
			throw new CoreException(error("method or field not found"));
		}

		try {
			Field field = class_.getDeclaredField(name);
			// Can't be null -- NoSuchFieldException raised otherwise
			field.setAccessible(true);
			return field.get(object);
		} catch (IllegalArgumentException e) {
			// should not happen
			throw new CoreException(error(e, "Unexpected error getting field %s", name));
		} catch (SecurityException e) {
			throw new CoreException(error(e, "Unexpected error getting field %s", name));
		} catch (IllegalAccessException e) {
			throw new CoreException(error(e, "Unexpected error getting field %s", name));
		} catch (NoSuchFieldException e) {
			return getFieldValue(class_.getSuperclass(), object, name);
		}

	}

	private static IStatus processArrayMethod(Object array, String name, Object[] args, IPipe out)
			throws CoreException {
		if (name.equals("get")) {
			if (args.length != 1)
				return error("Invalid number of arguments.");
			Object index = convert(int.class, args[0], true, true);
			if (index == NOT_CONVERTIBLE)
				return error("Invalid index type.");

			Object result = Array.get(array, (Integer) index);
			if (result != null)
				out.write(result);

			return Status.OK_STATUS;
		} else if (name.equals("set")) {
			if (args.length != 2)
				return error("Invalid number of arguments.");

			Object index = convert(int.class, args[0], true, true);
			if (index == NOT_CONVERTIBLE)
				return error("Invalid index type.");

			Object value = convert(array.getClass().getComponentType(), args[1], true, true);
			if (value == NOT_CONVERTIBLE)
				return error("Invalid value type.");

			Array.set(array, (Integer) index, value);

			return Status.OK_STATUS;
		} else if (name.equals("length")) {
			if (args.length != 0)
				return error("Invalid number of arguments.");

			out.write(Array.getLength(array));
			return Status.OK_STATUS;
		} else
			return error("Unknown array pseudo-method name.");
	}

	@SuppressWarnings("rawtypes")
	static Method matchMethod(Class class_, String name, Object[] args) {
		Method result = matchMethod(class_, name, args, false, false);
		if (result == null)
			result = matchMethod(class_, name, args, true, false);
		if (result == null)
			result = matchMethod(class_, name, args, true, true);
		return result;
	}

	/*
	 * TODO:
	 *
	 * 1. Null handling. 2. Proper overloading resolution.
	 *
	 * Standard says we must select the most "specific" method.
	 *
	 * 3. What will happen if arrays passed?
	 *
	 * Useful reading:
	 * http://geekexplains.blogspot.com/2009/06/choosing-most-specific
	 * -method-tricky.html
	 */
	@SuppressWarnings({ "rawtypes" })
	static Method matchMethod(Class class_, String name, Object[] args, boolean doWiden, boolean doNarrow) {
		final Method[] methods = class_.getMethods();

		for (Method m : methods) {
			if (!m.getName().equals(name))
				continue;

			final Class[] paramTypes = m.getParameterTypes();
			if (paramTypes.length != args.length)
				continue;

			boolean done = true;
			for (int i = 0; i < paramTypes.length; ++i) {
				if (convert(paramTypes[i], args[i], doWiden, doNarrow) == NOT_CONVERTIBLE) {
					done = false;
					break;
				}
			}

			if (done)
				return m;
		}

		return null;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private static Object convert(Class to, Object value, boolean doWiden, boolean doNarrow) {

		Class from = value.getClass();

		// if Java tells us it is convertible, let it go
		if (to.isAssignableFrom(from))
			return value;

		to = toPrimitive(to);
		from = toPrimitive(from);

		// if one of the types or both are not convertible to primitive,
		// we can not do anything about it
		if (to == null || from == null)
			return NOT_CONVERTIBLE;

		// always self assignable
		if (to == from)
			return value;

		if (doWiden) {
			// try to widen
			Object converted = widden(to, value);
			if (converted != NOT_CONVERTIBLE)
				return converted;
		}

		if (doNarrow) {
			// try to narrow
			Object converted = narrow(to, value);
			if (converted != NOT_CONVERTIBLE)
				return converted;
		}

		return NOT_CONVERTIBLE;
	}

	@SuppressWarnings("rawtypes")
	private static Object widden(Class to, Object value) {

		if (to == value.getClass())
			return value;
		if (to == toPrimitive(value.getClass()))
			return value;

		Number number = null;
		Character character = null;

		if (value instanceof Number)
			number = (Number) value;
		if (value instanceof Character)
			character = (Character) value;

		if (to == long.class) {
			if (value instanceof Byte || value instanceof Short || value instanceof Integer)
				return new Long(number.longValue());
			else if (value instanceof Character)
				return new Long(character.charValue());
			else
				return NOT_CONVERTIBLE;
		}

		if (to == int.class) {
			if (value instanceof Byte || value instanceof Short)
				return new Integer(number.intValue());
			else if (value instanceof Character)
				return new Integer(character.charValue());
			else
				return NOT_CONVERTIBLE;
		}

		if (to == short.class) {
			if (value instanceof Byte)
				return new Short(number.shortValue());
			else
				return NOT_CONVERTIBLE;
		}

		if (to == byte.class) {
			return NOT_CONVERTIBLE; // nothing can be widened to byte
		}

		if (to == double.class) {
			if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long
					|| value instanceof Float)
				return new Double(number.doubleValue());
			else if (value instanceof Character)
				return new Double(character.charValue());
			else
				return NOT_CONVERTIBLE;
		}

		if (to == float.class) {
			if (value instanceof Byte || value instanceof Short || value instanceof Integer || value instanceof Long)
				return new Float(number.floatValue());
			else if (value instanceof Character)
				return new Float(character.charValue());
			else
				return NOT_CONVERTIBLE;
		}

		if (to == char.class) {
			return NOT_CONVERTIBLE; // nothing can be widened to char
		}

		return NOT_CONVERTIBLE;
	}

	@SuppressWarnings("rawtypes")
	private static Object narrow(Class to, Object value) {
		if (to == value.getClass())
			return value;
		if (to == toPrimitive(value.getClass()))
			return value;

		Number number = null;
		Character character = null;

		if (value instanceof Number)
			number = (Number) value;
		if (value instanceof Character)
			character = (Character) value;

		if (to == long.class) {
			if (value instanceof Number) {
				long l = number.longValue();
				double d = number.doubleValue();
				if (l == d && d >= Long.MIN_VALUE && d <= Long.MAX_VALUE)
					return new Long(l);
				else
					return NOT_CONVERTIBLE;
			} else
				return NOT_CONVERTIBLE;
		}

		if (to == int.class) {
			if (value instanceof Number) {
				long l = number.longValue();
				double d = number.doubleValue();
				if (l == d && l >= Integer.MIN_VALUE && l <= Integer.MAX_VALUE)
					return new Integer((int) l);
				else
					return NOT_CONVERTIBLE;
			} else
				return NOT_CONVERTIBLE;
		}

		if (to == short.class) {
			if (value instanceof Number) {
				long l = number.longValue();
				double d = number.doubleValue();
				if (l == d && l >= Short.MIN_VALUE && l <= Short.MAX_VALUE)
					return new Short((short) l);
				else
					return NOT_CONVERTIBLE;
			} else if (value instanceof Character) {
				char c = character.charValue();
				if (c >= Short.MIN_VALUE && c <= Short.MAX_VALUE)
					return new Short((short) c);
				else
					return NOT_CONVERTIBLE;
			} else
				return NOT_CONVERTIBLE;
		}

		if (to == byte.class) {
			if (value instanceof Number) {
				long l = number.longValue();
				double d = number.doubleValue();
				if (l == d && l >= Byte.MIN_VALUE && l <= Byte.MAX_VALUE)
					return new Byte((byte) l);
				else
					return NOT_CONVERTIBLE;
			} else if (value instanceof Character) {
				char c = character.charValue();
				if (c >= Byte.MIN_VALUE && c <= Byte.MAX_VALUE)
					return new Byte((byte) c);
				else
					return NOT_CONVERTIBLE;
			} else
				return NOT_CONVERTIBLE;
		}

		if (to == double.class) {
			return NOT_CONVERTIBLE; // double is the widest type in the world
		}

		if (to == float.class) {
			if (value instanceof Double) {
				double d = number.doubleValue();
				if (d >= Float.MIN_VALUE && d <= Float.MAX_VALUE)
					return new Float((float) d);
				else
					return NOT_CONVERTIBLE;
			} else
				return NOT_CONVERTIBLE;
		}

		if (to == char.class) {
			if (value instanceof Number) {
				long l = number.longValue();
				double d = number.doubleValue();
				if (l == d && l >= Character.MIN_VALUE && l <= Character.MAX_VALUE)
					return new Character((char) l);
				else
					return NOT_CONVERTIBLE;
			} else
				return NOT_CONVERTIBLE;
		}

		return NOT_CONVERTIBLE;
	}

	@SuppressWarnings("rawtypes")
	private static Class toPrimitive(Class boxed) {
		if (boxed.isPrimitive())
			return boxed;

		if (boxed == Boolean.class)
			return boolean.class;
		if (boxed == Character.class)
			return char.class;
		if (boxed == Byte.class)
			return byte.class;
		if (boxed == Short.class)
			return short.class;
		if (boxed == Integer.class)
			return int.class;
		if (boxed == Long.class)
			return long.class;
		if (boxed == Float.class)
			return float.class;
		if (boxed == Double.class)
			return double.class;

		return null;
	}
}
