/*******************************************************************************
 * Copyright (c) 2016 Obeo.
 * 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.acceleo.query.runtime.impl;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.acceleo.query.ast.Call;
import org.eclipse.acceleo.query.parser.CombineIterator;
import org.eclipse.acceleo.query.runtime.AcceleoQueryValidationException;
import org.eclipse.acceleo.query.runtime.ICompletionProposal;
import org.eclipse.acceleo.query.runtime.IReadOnlyQueryEnvironment;
import org.eclipse.acceleo.query.runtime.IValidationResult;
import org.eclipse.acceleo.query.runtime.impl.completion.EOperationServiceCompletionProposal;
import org.eclipse.acceleo.query.validation.type.ClassType;
import org.eclipse.acceleo.query.validation.type.EClassifierLiteralType;
import org.eclipse.acceleo.query.validation.type.EClassifierType;
import org.eclipse.acceleo.query.validation.type.IJavaType;
import org.eclipse.acceleo.query.validation.type.IType;
import org.eclipse.acceleo.query.validation.type.SequenceType;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EParameter;
import org.eclipse.emf.ecore.EcorePackage;

/**
 * Abstract implementation of an {@link org.eclipse.acceleo.query.runtime.IService IService} for
 * {@link EOperation}.
 * 
 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
 * @since 4.1
 */
public class EOperationService extends AbstractService<EOperation> {

	/**
	 * The {@link org.eclipse.acceleo.query.runtime.IService#getPriority() priority} for
	 * {@link EOperationService}.
	 */
	public static final int PRIORITY = 100;

	/**
	 * Log message used when a called EOperation can't be invoked.
	 */
	protected static final String COULDN_T_INVOKE_EOPERATION = "Couldn't invoke the %s EOperation (%s)";

	/**
	 * The Java method which actually implements the EOperation.
	 */
	private final Method method;

	/**
	 * Creates a new service instance given a method and an instance.
	 * 
	 * @param eOperation
	 *            the {@link EOperation} that realizes the service
	 */
	public EOperationService(EOperation eOperation) {
		super(eOperation);
		this.method = lookupMethod(eOperation);
	}

	/**
	 * Finds the Java {@link Method} which implements a given {@link EOperation}.
	 * 
	 * @param operation
	 *            the {@link EOperation} to look for.
	 * @return the Java method which implements the {@link EOperation}, or <code>null</code> if none could be
	 *         found.
	 */
	private Method lookupMethod(EOperation operation) {
		Method result;

		final Class<?> containerClass = operation.getEContainingClass().getInstanceClass();
		if (containerClass != null) {
			final Class<?>[] argumentClasses = new Class<?>[operation.getEParameters().size()];
			for (int i = 0; i < argumentClasses.length; i++) {
				EParameter param = operation.getEParameters().get(i);
				if (param.isMany()) {
					argumentClasses[i] = EList.class;
				} else {
					argumentClasses[i] = param.getEType().getInstanceClass();
				}
			}
			try {
				result = containerClass.getMethod(operation.getName(), argumentClasses);
			} catch (SecurityException e) {
				result = null;
			} catch (NoSuchMethodException e) {
				result = null;
			}
		} else {
			result = null;
		}

		return result;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.IService#getName()
	 */
	@Override
	public String getName() {
		return getOrigin().getName();
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.IService#getParameterTypes(org.eclipse.acceleo.query.runtime.IReadOnlyQueryEnvironment)
	 */
	@Override
	public List<IType> getParameterTypes(IReadOnlyQueryEnvironment queryEnvironment) {
		final List<IType> result = new ArrayList<IType>();

		result.add(new EClassifierType(queryEnvironment, getOrigin().getEContainingClass()));
		for (EParameter parameter : getOrigin().getEParameters()) {
			final EClassifierType rawType = new EClassifierType(queryEnvironment, parameter.getEType());
			if (parameter.isMany()) {
				result.add(new SequenceType(queryEnvironment, rawType));
			} else {
				result.add(rawType);
			}
		}

		return result;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.IService#getNumberOfParameters()
	 */
	@Override
	public int getNumberOfParameters() {
		return getOrigin().getEParameters().size() + 1;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.impl.AbstractService#internalInvoke(java.lang.Object[])
	 */
	@Override
	protected Object internalInvoke(Object[] arguments) throws Exception {
		final Object result;
		final EObject receiver = (EObject)arguments[0];
		final Object[] localArguments = new Object[arguments.length];
		for (int i = 1; i < arguments.length; ++i) {
			if (getOrigin().getEParameters().get(i - 1).isMany()) {
				localArguments[i] = new BasicEList<Object>((Collection<?>)arguments[i]);
			} else {
				localArguments[i] = arguments[i];
			}
		}

		if (!getOrigin().getEContainingClass().isSuperTypeOf(receiver.eClass())) {
			if (method != null) {
				final Object[] parameters = Arrays.copyOfRange(localArguments, 1, localArguments.length);
				result = eOperationJavaInvoke(method, receiver, parameters);
			} else {
				throw new IllegalStateException(String.format(
						"EOperation %s not in %s type hierarchy of %s and no %s method in %s", getName(),
						getOrigin().getEContainingClass().getName(), receiver.eClass().getName(), getName(),
						receiver.getClass().getName()));
			}
		} else if (hasEInvoke(receiver)) {
			final EList<Object> eArguments = new BasicEList<Object>(localArguments.length);
			for (int i = 1; i < localArguments.length; ++i) {
				eArguments.add(localArguments[i]);
			}
			result = receiver.eInvoke(getOrigin(), eArguments);
		} else if (method != null) {
			final Object[] parameters = Arrays.copyOfRange(localArguments, 1, localArguments.length);
			result = eOperationJavaInvoke(method, receiver, parameters);
		} else {
			throw new IllegalStateException(String.format("No eInvoke nor %s methods in %s", getName(),
					receiver.getClass().getName()));
		}

		return result;
	}

	/**
	 * Try to find out if the Operation reflection is enable for the given {@link Object}.
	 * 
	 * @param object
	 *            the {@link Object} to test.
	 * @return <code>true</code> if the Operation reflection is enable for the given {@link Object},
	 *         <code>false</code> otherwise
	 */
	private boolean hasEInvoke(Object object) {
		Method eInvokeMethod = null;

		try {
			eInvokeMethod = object.getClass().getDeclaredMethod("eInvoke", int.class, EList.class);
		} catch (NoSuchMethodException e) {
			// nothing to do here
		} catch (SecurityException e) {
			// nothing to do here
		}

		return eInvokeMethod != null;
	}

	/**
	 * Call the {@link EOperation} thru a Java invoke.
	 * 
	 * @param eInvokeMethod
	 *            the {@link Method}
	 * @param receiver
	 *            the receiver
	 * @param arguments
	 *            arguments
	 * @return the {@link EOperation} result if any, {@link Nothing} otherwise
	 * @throws Exception
	 *             if the invoked {@link EOperation} fail
	 */
	private Object eOperationJavaInvoke(Method eInvokeMethod, final Object receiver, final Object[] arguments)
			throws Exception {
		if (eInvokeMethod != null && receiver != null) {
			return eInvokeMethod.invoke(receiver, arguments);
		} else {
			throw new IllegalArgumentException();
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.IService#getPriority()
	 */
	@Override
	public int getPriority() {
		return PRIORITY;
	}

	@Override
	public Set<IType> getType(Call call, ValidationServices services, IValidationResult validationResult,
			IReadOnlyQueryEnvironment queryEnvironment, List<IType> argTypes) {
		final Set<IType> result = new LinkedHashSet<IType>();

		final IType eClassifierType = new EClassifierType(queryEnvironment, getOrigin().getEType());
		if (getOrigin().isMany()) {
			result.add(new SequenceType(queryEnvironment, eClassifierType));
		} else {
			result.add(eClassifierType);
		}

		return result;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.impl.AbstractService#matches(org.eclipse.acceleo.query.runtime.IReadOnlyQueryEnvironment,
	 *      org.eclipse.acceleo.query.validation.type.IType[])
	 */
	@Override
	public boolean matches(IReadOnlyQueryEnvironment queryEnvironment, IType[] argumentTypes) {
		final List<Set<IType>> eClassifierTypes = new ArrayList<Set<IType>>(argumentTypes.length);

		boolean canMatch = true;
		for (int i = 0; i < argumentTypes.length; ++i) {
			Set<EClassifier> eClassifiers;
			final IType iType = argumentTypes[i];
			if (iType instanceof EClassifierLiteralType) {
				eClassifiers = new LinkedHashSet<EClassifier>();
				eClassifiers.add(EcorePackage.eINSTANCE.getEClass());
			} else if (iType instanceof EClassifierType) {
				eClassifiers = new LinkedHashSet<EClassifier>();
				eClassifiers.add(((EClassifierType)iType).getType());
			} else if (iType instanceof SequenceType) {
				eClassifiers = new LinkedHashSet<EClassifier>();
				eClassifiers.add(EcorePackage.eINSTANCE.getEEList());
			} else if (iType instanceof IJavaType) {
				if (iType.getType() == null) {
					eClassifiers = new LinkedHashSet<EClassifier>();
					eClassifiers.add(null);
				} else if (List.class.isAssignableFrom(((IJavaType)iType).getType())) {
					eClassifiers = new LinkedHashSet<EClassifier>();
					eClassifiers.add(EcorePackage.eINSTANCE.getEEList());
				} else {
					eClassifiers = queryEnvironment.getEPackageProvider().getEClassifiers(((IJavaType)iType)
							.getType());
					if (eClassifiers == null) {
						canMatch = false;
						break;
					}
				}
			} else {
				throw new AcceleoQueryValidationException(iType.getClass().getCanonicalName());
			}
			final Set<IType> types = new LinkedHashSet<IType>();
			for (EClassifier eClassifier : eClassifiers) {
				if (eClassifier != null) {
					types.add(new EClassifierType(queryEnvironment, eClassifier));
				} else {
					types.add(new ClassType(queryEnvironment, null));
				}
			}
			eClassifierTypes.add(types);
		}

		if (canMatch) {
			CombineIterator<IType> it = new CombineIterator<IType>(eClassifierTypes);
			boolean matched = false;
			while (it.hasNext()) {
				final List<IType> parameterTypes = it.next();
				if (super.matches(queryEnvironment, parameterTypes.toArray(new IType[parameterTypes
						.size()]))) {
					matched = true;
					break;
				}
			}
			canMatch = matched;
		}

		return canMatch;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.IService#getShortSignature()
	 */
	@Override
	public String getShortSignature() {
		final List<IType> parameterTypes = getParameterTypes(null);
		final IType[] argumentTypes = parameterTypes.toArray(new IType[parameterTypes.size()]);

		return serviceShortSignature(argumentTypes);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see org.eclipse.acceleo.query.runtime.IService#getLongSignature()
	 */
	@Override
	public String getLongSignature() {
		final String ePkgNsURI;
		final String eCLassName;

		final EClass eContainingClass = getOrigin().getEContainingClass();
		if (eContainingClass != null) {
			eCLassName = eContainingClass.getName();
			final EPackage ePackage = eContainingClass.getEPackage();
			if (ePackage != null) {
				ePkgNsURI = ePackage.getNsURI();
			} else {
				ePkgNsURI = null;
			}
		} else {
			ePkgNsURI = null;
			eCLassName = null;
		}

		return ePkgNsURI + " " + eCLassName + " " + getShortSignature();
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		return obj instanceof EOperationService && ((EOperationService)obj).getOrigin().equals(getOrigin());
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return getOrigin().hashCode();
	}

	@Override
	public List<ICompletionProposal> getProposals(IReadOnlyQueryEnvironment queryEnvironment,
			Set<IType> receiverTypes) {
		final List<ICompletionProposal> result = new ArrayList<ICompletionProposal>();

		result.add(new EOperationServiceCompletionProposal(getOrigin()));

		return result;
	}

}
