/*****************************************************************************
 * 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
 *   Christian W. Damus (CEA) - bug 443830
 *   
 *****************************************************************************/
package org.eclipse.papyrus.cdo.internal.ui.views;

import java.util.Iterator;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.plugin.RegistryReader;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.net4j.util.ui.views.IElementFilter;
import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
import org.eclipse.papyrus.cdo.internal.ui.Activator;
import org.osgi.framework.Bundle;

import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.Maps;


/**
 * This is the ItemProviderFilterRegistry type. Enjoy.
 */
class ItemProviderFilterRegistry {

	static final ItemProviderFilterRegistry INSTANCE = new ItemProviderFilterRegistry();

	private final Map<String, Filter> filters = Maps.newHashMap();

	private ItemProviderFilterRegistry() {
		super();

		new MyRegistryReader().readRegistry();
	}

	public Predicate<Object> createFilter(ILabelProvider labelProvider) {
		return new CompositeFilter(labelProvider);
	}

	//
	// Nested types
	//

	final class CompositeFilter implements Predicate<Object> {

		private final ILabelProvider labelProvider;

		private final LabelWrapper labelWrapper = new LabelWrapper();

		CompositeFilter(ILabelProvider labelProvider) {
			super();

			this.labelProvider = labelProvider;
		}

		@Override
		public boolean apply(Object input) {
			boolean result = true;

			if (!filters.isEmpty()) {
				labelWrapper.object = input;
				labelWrapper.label = labelProvider.getText(input);

				for (Iterator<Filter> iter = filters.values().iterator(); result && iter.hasNext();) {
					result = !iter.next().apply(labelWrapper);
				}
			}

			return result;
		}
	}

	static final class LabelWrapper {

		Object object;

		String label;

		LabelWrapper() {
			super();
		}
	}

	static abstract class Filter implements Predicate<LabelWrapper> {

		final String id;

		Filter(String id) {
			super();

			this.id = id;
		}

		String getID() {
			return id;
		}
	}

	static class LabelPatternFilter extends Filter {

		private final Pattern pattern;

		LabelPatternFilter(String id, String pattern) {
			super(id);

			this.pattern = Pattern.compile(pattern);
		}

		@Override
		public boolean apply(LabelWrapper input) {
			return (input.label != null) && pattern.matcher(input.label).find();
		}

	}

	static class LabelPatternFilterWithObjectClass extends LabelPatternFilter {

		private final Class<?> objectClass;

		private final boolean adapt;

		LabelPatternFilterWithObjectClass(String id, String pattern, Class<?> objectClass, boolean adapt) {
			super(id, pattern);

			this.objectClass = objectClass;
			this.adapt = adapt;
		}

		@Override
		public boolean apply(LabelWrapper input) {
			return adapts(input.object) && super.apply(input);
		}

		private boolean adapts(Object object) {
			return adapt ? (CDOUtils.adapt(object, objectClass) != null) : objectClass.isInstance(object);
		}
	}

	static class ElementFilterFilter extends Filter {

		private final Supplier<? extends IElementFilter> filter;

		private boolean enabled = true;

		ElementFilterFilter(String id, Supplier<? extends IElementFilter> filter) {
			super(id);

			this.filter = filter;
		}

		@Override
		public boolean apply(LabelWrapper input) {
			try {
				return enabled && filter.get().filter(input.object);
			} catch (Exception e) {
				Activator.log.error("Uncaught exception in element filter. Filter will be disabled.", e); //$NON-NLS-1$
				enabled = false;
				return false;
			}
		}
	}

	static class PredicateFilter extends Filter {

		private final Supplier<? extends Predicate<Object>> predicate;

		private boolean enabled = true;

		PredicateFilter(String id, Supplier<? extends Predicate<Object>> predicate) {
			super(id);

			this.predicate = predicate;
		}

		@Override
		public boolean apply(LabelWrapper input) {
			try {
				return enabled && predicate.get().apply(input.object);
			} catch (Exception e) {
				Activator.log.error("Uncaught exception in predicate. Filter will be disabled.", e); //$NON-NLS-1$
				enabled = false;
				return false;
			}
		}
	}

	class MyRegistryReader extends RegistryReader {

		static final String EXT_PT = "repositoryFilters"; //$NON-NLS-1$

		static final String E_ITEM_PROVIDER_FILTER = "itemProviderFilter"; //$NON-NLS-1$

		static final String A_ID = "id"; //$NON-NLS-1$

		static final String E_LABEL_PATTERN = "labelPattern"; //$NON-NLS-1$

		static final String A_PATTERN = "pattern"; //$NON-NLS-1$

		static final String A_OBJECT_CLASS = "objectClass"; //$NON-NLS-1$

		static final String A_ADAPT = "adapt"; //$NON-NLS-1$

		static final String E_ELEMENT_FILTER = "elementFilter"; //$NON-NLS-1$

		static final String A_CLASS = "class"; //$NON-NLS-1$

		static final String A_SUPPLIER_CLASS = "supplierClass"; //$NON-NLS-1$

		static final String E_PREDICATE = "predicate"; //$NON-NLS-1$

		private String currentID;

		private IConfigurationElement currentConfig;

		MyRegistryReader() {
			super(Platform.getExtensionRegistry(), Activator.PLUGIN_ID, EXT_PT);
		}

		@Override
		protected boolean readElement(IConfigurationElement config, boolean add) {
			boolean result = true;

			final String name = config.getName();

			if (E_ITEM_PROVIDER_FILTER.equals(name)) {
				String id = config.getAttribute(A_ID);
				if (id == null) {
					result = false;
					logMissingAttribute(config, A_ID);
					currentID = null;
					currentConfig = null;
				} else {
					if (add) {
						if (currentID != null) {
							// haven't created the previous filter
							logError(currentConfig, String.format("Missing specification of filter %s.", currentID)); //$NON-NLS-1$
						}

						currentID = id;
						currentConfig = config;
					} else if (id != null) {
						removeFilter(id);
					}
				}
			} else if (add) { // don't need to process deletion of filter specifications, only filters
				if (currentID == null) {
					result = false;
					logError(config, String.format("Too many filter specifications.")); //$NON-NLS-1$
				} else if (filters.containsKey(currentID)) {
					result = false;
					logError(config, String.format("Duplicate filter ID \"%s\".  The duplicate is ignored.", currentID)); //$NON-NLS-1$
				} else {
					result = createFilter(config);
				}
			}

			return result;
		}

		void removeFilter(String id) {
			filters.remove(id);
		}

		boolean createFilter(IConfigurationElement config) {
			boolean result = false;

			final String name = config.getName();

			if (E_LABEL_PATTERN.equals(name)) {
				result = createLabelPatternFilter(config);
			} else if (E_ELEMENT_FILTER.equals(name)) {
				result = createElementFilterFilter(config);
			} else if (E_PREDICATE.equals(name)) {
				result = createPredicateFilter(config);
			}

			return result;
		}

		private void addFilter(Filter filter) {
			filters.put(currentID, filter);
			currentID = null;
			currentConfig = null;
		}

		boolean createLabelPatternFilter(IConfigurationElement config) {
			boolean result = true;

			String pattern = config.getAttribute(A_PATTERN);
			if (pattern == null) {
				logMissingAttribute(config, A_PATTERN);
				result = false;
			} else {
				Class<?> objectClass = null;
				String className = config.getAttribute(A_OBJECT_CLASS);

				if (className != null) {
					String bundleID = config.getContributor().getName();

					try {
						Bundle bundle = Platform.getBundle(bundleID);
						objectClass = bundle.loadClass(className);
					} catch (Exception e) {
						result = false;
						logError(config, String.format("Could not find class \"%s\" in bundle \"%s\".", className, bundleID)); //$NON-NLS-1$
					}
				}

				if (result) {
					try {
						if (objectClass == null) {
							addFilter(new LabelPatternFilter(currentID, pattern));
						} else {
							boolean adapt = false;
							String adaptAttr = config.getAttribute(A_ADAPT);
							if (adaptAttr != null) {
								adapt = Boolean.parseBoolean(adaptAttr);
							}

							addFilter(new LabelPatternFilterWithObjectClass(currentID, pattern, objectClass, adapt));
						}
					} catch (Exception e) {
						result = false;
						Activator.log.error(e);
						logError(config, String.format("Failed to initialize filter on pattern \"%s\".", pattern)); //$NON-NLS-1$
					}
				}
			}

			return result;
		}

		boolean createElementFilterFilter(IConfigurationElement config) {
			boolean result = true;

			String className = config.getAttribute(A_CLASS);
			String supplierClassName = config.getAttribute(A_SUPPLIER_CLASS);

			if ((className == null) && (supplierClassName == null)) {
				result = false;
				logMissingAttribute(config, A_CLASS);
			} else if (className != null) {
				try {
					Object extension = config.createExecutableExtension(A_CLASS);
					if (!(extension instanceof IElementFilter)) {
						result = false;
						logError(config, String.format("Extension is not an IElementFilter: %s", extension.getClass().getName())); //$NON-NLS-1$
					}

					addFilter(new ElementFilterFilter(currentID, Suppliers.ofInstance((IElementFilter) extension)));
				} catch (CoreException e) {
					result = false;
					Activator.log.error(e);
				}
			} else {
				try {
					Object extension = config.createExecutableExtension(A_CLASS);
					if (!(extension instanceof Supplier<?>)) {
						result = false;
						logError(config, String.format("Extension is not a Supplier<? extends IElementFilter>: %s", extension.getClass().getName())); //$NON-NLS-1$
					}

					@SuppressWarnings("unchecked")
					Supplier<? extends IElementFilter> supplier = (Supplier<? extends IElementFilter>) extension;
					addFilter(new ElementFilterFilter(currentID, Suppliers.memoize(supplier)));
				} catch (CoreException e) {
					result = false;
					Activator.log.error(e);
				}
			}

			return result;
		}

		boolean createPredicateFilter(IConfigurationElement config) {
			boolean result = true;

			String className = config.getAttribute(A_CLASS);
			String supplierClassName = config.getAttribute(A_SUPPLIER_CLASS);

			if ((className == null) && (supplierClassName == null)) {
				result = false;
				logMissingAttribute(config, A_CLASS);
			} else if (className != null) {
				try {
					Object extension = config.createExecutableExtension(A_CLASS);
					if (!(extension instanceof Predicate<?>)) {
						result = false;
						logError(config, String.format("Extension is not a Predicate<Object>: %s", extension.getClass().getName())); //$NON-NLS-1$
					}

					@SuppressWarnings("unchecked")
					Predicate<Object> predicate = (Predicate<Object>) extension;
					addFilter(new PredicateFilter(currentID, Suppliers.ofInstance(predicate)));
				} catch (CoreException e) {
					result = false;
					Activator.log.error(e);
				}
			} else {
				try {
					Object extension = config.createExecutableExtension(A_CLASS);
					if (!(extension instanceof Supplier<?>)) {
						result = false;
						logError(config, String.format("Extension is not a Supplier<? extends Predicate<Object>>: %s", extension.getClass().getName())); //$NON-NLS-1$
					}

					@SuppressWarnings("unchecked")
					Supplier<? extends Predicate<Object>> supplier = (Supplier<? extends Predicate<Object>>) extension;
					addFilter(new PredicateFilter(currentID, Suppliers.memoize(supplier)));
				} catch (CoreException e) {
					result = false;
					Activator.log.error(e);
				}
			}

			return result;
		}
	}
}
