/*******************************************************************************
 * Copyright (c) 2011 Mia-Software.
 * 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:
 *    Fabien Giquel (Mia-Software) - initial API and implementation
 *    Nicolas Bros (Mia-Software) - Bug 338702 - [Discovery] specify initial value for Parameters
 *******************************************************************************/
package org.eclipse.modisco.infra.discovery.core.internal;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.gmt.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.modisco.infra.discovery.catalog.DirectionKind;
import org.eclipse.modisco.infra.discovery.catalog.DiscovererDescription;
import org.eclipse.modisco.infra.discovery.catalog.DiscovererParameter;
import org.eclipse.modisco.infra.discovery.core.IDiscoverer;
import org.eclipse.modisco.infra.discovery.core.IDiscoveryManager;
import org.eclipse.modisco.infra.discovery.core.exception.DiscoveryException;
import org.eclipse.modisco.infra.discovery.core.internal.catalog.DiscovererRegistry;

/**
 * Registry for accessing {@link IDiscoverer} instances.
 *
 */
public final class DiscoveryManager implements IDiscoveryManager {

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * getDiscoverer(java.lang.String)
	 */
	public IDiscoverer<?> createDiscovererImpl(final String id) {
		DiscovererDescription discovererDescription = getDiscovererDescription(id);
		if (discovererDescription != null) {
			return createDiscovererImpl(discovererDescription);
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * getDiscoverer
	 * (org.eclipse.modisco.infra.discovery.catalog.DiscovererDescription)
	 */
	public IDiscoverer<?> createDiscovererImpl(final DiscovererDescription description) {
		return DiscovererRegistry.INSTANCE.createDiscoverer(description);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * getApplicableDiscoverers(java.lang.Object)
	 */
	public Collection<DiscovererDescription> getApplicableDiscoverers(final Object source) {
		Set<DiscovererDescription> result = new HashSet<DiscovererDescription>();
		for (DiscovererDescription aDiscoveryHandler : getDiscoverers()) {
			if (isApplicable(aDiscoveryHandler, source)) {
				result.add(aDiscoveryHandler);
			}
		}
		return Collections.unmodifiableSet(result);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * isApplicable
	 * (org.eclipse.modisco.infra.discovery.catalog.DiscovererDescription,
	 * java.lang.Object)
	 */
	@SuppressWarnings("unchecked")
	public boolean isApplicable(final DiscovererDescription discovererDefinition,
			final Object source) {
		// We must check the parameterized source type (T) of delegate
		// before calling isApplicableTo to avoid ClassCastException (case of
		// wildcard declarations)
		Class<?> discovererSourceType = discovererDefinition.getSourceType();
		// used a cached discoverer to avoid having to create a new instance
		// each time this method is called
		IDiscoverer<?> cachedDiscoverer = DiscovererRegistry.INSTANCE
				.getCachedDiscoverer(discovererDefinition);

		return discovererSourceType != null && discovererSourceType.isInstance(source)
				&& ((IDiscoverer<Object>) cachedDiscoverer).isApplicableTo(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * getDiscoverers()
	 */
	public Collection<DiscovererDescription> getDiscoverers() {
		return DiscovererRegistry.INSTANCE.getDiscovererDescriptions();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * getDiscovererDescription(java.lang.Class)
	 */
	public static DiscovererDescription getDiscovererDescription(final Class<?> discovererClass) {
		Collection<DiscovererDescription> discovererDescriptions = DiscovererRegistry.INSTANCE
				.getDiscovererDescriptions();
		for (DiscovererDescription discovererDescription : discovererDescriptions) {
			if (discovererClass.equals(discovererDescription.getImplementationType())) {
				return discovererDescription;
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * getDiscovererDescription(java.lang.String)
	 */
	public DiscovererDescription getDiscovererDescription(final String id) {
		for (DiscovererDescription discovererDescription : getDiscoverers()) {
			if (id.equals(discovererDescription.getId())) {
				return discovererDescription;
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * getDiscovererDescription
	 * (org.eclipse.modisco.infra.discovery.core.IDiscoverer)
	 */
	public DiscovererDescription getDiscovererDescription(final IDiscoverer<?> discoverer) {
		for (DiscovererDescription discovererDescription : getDiscoverers()) {
			if (discovererDescription.getImplementationType().equals(discoverer.getClass())) {
				return discovererDescription;
			}
			// IDiscoverer<?> cachedDiscoverer = DiscovererRegistry.INSTANCE
			// .getCachedDiscoverer(discovererDescription);
			// if (cachedDiscoverer.getClass().equals(discoverer.getClass())) {
			// return discovererDescription;
			// }
		}
		return null;
	}

	/**
	 * This method computes at runtime the source type argument for one
	 * discoverer implementation (generic T type)
	 */
	protected static void computeSourceType(final DiscovererDescription discovererDescription) {
		Class<?> sourceType = null;
		try {
			// At runtime we look for the "isApplicableTo(T)" method to deduce
			// the instantiated T type
			for (Method aMethod : discovererDescription.getImplementationType().getMethods()) {
				if (aMethod.getName().equals("isApplicableTo") //$NON-NLS-1$
						&& aMethod.getParameterTypes().length == 1) {
					Class<?> parameterClass = aMethod.getParameterTypes()[0];
					if (sourceType == null || parameterClass != java.lang.Object.class) {
						sourceType = parameterClass;
					}
				}
			}
		} catch (IllegalArgumentException e) {
			MoDiscoLogger.logWarning(e, Activator.getDefault());
		}
		discovererDescription.setSourceType(sourceType);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * canRetrieveValue
	 * (org.eclipse.modisco.infra.discovery.catalog.DiscovererParameter)
	 */
	public boolean canRetrieveValue(final DiscovererParameter parameter) {
		boolean result = parameter.getField() != null
				&& Modifier.isPublic(parameter.getField().getModifiers());
		result = result
				|| (parameter.getGetter() != null && Modifier.isPublic(parameter.getGetter()
						.getModifiers()));

		return result;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#getValue
	 * (org.eclipse.modisco.infra.discovery.catalog.DiscovererParameter,
	 * org.eclipse.modisco.infra.discovery.core.IDiscoverer)
	 */
	public Object getValue(final DiscovererParameter parameter, final IDiscoverer<?> discoverer)
			throws DiscoveryException {
		Object parameterValue = null;
		try {
			if (parameter.getField() != null
					&& Modifier.isPublic(parameter.getField().getModifiers())) {
				parameterValue = parameter.getField().get(discoverer);
			} else if (parameter.getGetter() != null
					&& Modifier.isPublic(parameter.getGetter().getModifiers())) {
				parameterValue = parameter.getGetter().invoke(discoverer);
			} else {
				throw new DiscoveryException(discoverer.getClass()
						+ " discoverer does not implement public read access to the parameter " //$NON-NLS-1$
						+ parameter.getId());
			}
		} catch (IllegalArgumentException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId(), e);
		} catch (IllegalAccessException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId(), e);
		} catch (InvocationTargetException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId(), e);
		}

		return parameterValue;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#setValue
	 * (org.eclipse.modisco.infra.discovery.catalog.DiscovererParameter,
	 * org.eclipse.modisco.infra.discovery.core.IDiscoverer, java.lang.Object)
	 */
	public void setValue(final DiscovererParameter parameter, final IDiscoverer<?> discoverer,
			final Object parameterValue) throws DiscoveryException {
		try {
			if (parameter.getField() != null
					&& Modifier.isPublic(parameter.getField().getModifiers())) {
				parameter.getField().set(discoverer, parameterValue);
			} else if (parameter.getSetter() != null
					&& Modifier.isPublic(parameter.getSetter().getModifiers())) {
				parameter.getSetter().invoke(discoverer, parameterValue);
			} else {
				throw new DiscoveryException(discoverer.getClass()
						+ " discoverer does not implement public write access to the parameter " //$NON-NLS-1$
						+ parameter.getId());
			}
		} catch (IllegalArgumentException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId() + " : " + parameterValue, e); //$NON-NLS-1$
		} catch (IllegalAccessException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId() + " : " + parameterValue, e); //$NON-NLS-1$
		} catch (InvocationTargetException e) {
			throw new DiscoveryException("Illegal parameter value for " //$NON-NLS-1$
					+ parameter.getId() + " : " + parameterValue, e); //$NON-NLS-1$
		}

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.modisco.infra.discovery.core.catalog.IDiscoveryManager#
	 * discoverElement(org.eclipse.modisco.infra.discovery.core.IDiscoverer,
	 * java.lang.Object, java.util.Map)
	 */
	@SuppressWarnings("unchecked")
	public void discoverElement(final IDiscoverer<?> discoverer, final Object source,
			final Map<String, Object> parametersValues, final IProgressMonitor monitor)
			throws DiscoveryException {
		DiscovererDescription discoDesc = getDiscovererDescription(discoverer);

		// affect parameters input values
		for (Map.Entry<String, Object> entry : parametersValues.entrySet()) {
			DiscovererParameter parameter = discoDesc.getParameterDefinition(entry.getKey());
			if (parameter == null) {
				throw new DiscoveryException("Illegal parameter name : " + entry.getKey() //$NON-NLS-1$
						+ " for discoverer : " + discoDesc.getId()); //$NON-NLS-1$
			}
			setValue(parameter, discoverer, entry.getValue());
		}

		final IProgressMonitor progressMonitor;
		if (monitor != null) {
			progressMonitor = monitor;
		} else {
			progressMonitor = new NullProgressMonitor();
		}
		// launch discovery
		((IDiscoverer<Object>) discoverer).discoverElement(source, progressMonitor);

		// give output values
		for (DiscovererParameter parameter : discoDesc.getParameterDefinitions()) {
			if (parameter.getDirection().equals(DirectionKind.OUT)
					|| parameter.getDirection().equals(DirectionKind.INOUT)) {
				parametersValues.put(parameter.getId(), getValue(parameter, discoverer));
			}
		}
	}

	public boolean hasInitialValue(final DiscovererParameter parameter,
			final DiscovererDescription discoverer) {
		return parameter.getInitializer() != null
				&& Modifier.isPublic(parameter.getInitializer().getModifiers());
	}

	public Object getInitialValue(final DiscovererParameter parameter,
			final DiscovererDescription discoverer, final Object source) throws DiscoveryException {
		Object parameterValue = null;
		try {
			if (parameter.getInitializer() != null) {
				if (Modifier.isPublic(parameter.getInitializer().getModifiers())) {
					IDiscoverer<?> cachedDiscoverer = DiscovererRegistry.INSTANCE
							.getCachedDiscoverer(discoverer);
					parameterValue = parameter.getInitializer().invoke(cachedDiscoverer, source);
				} else {
					throw new DiscoveryException(
							discoverer.getClass()
									+ " discoverer does not implement public read access to the parameter initializer " //$NON-NLS-1$
									+ parameter.getId());
				}
			} else {
				return null;
			}
		} catch (IllegalArgumentException e) {
			throw new DiscoveryException("Illegal parameter initializer for " //$NON-NLS-1$
					+ parameter.getId(), e);
		} catch (IllegalAccessException e) {
			throw new DiscoveryException("Illegal parameter initializer for " //$NON-NLS-1$
					+ parameter.getId(), e);
		} catch (InvocationTargetException e) {
			throw new DiscoveryException("Illegal parameter initializer for " //$NON-NLS-1$
					+ parameter.getId(), e);
		}
		return parameterValue;
	}
}
