/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation and others.
 *
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Sergey Prigogin (Google) - Bug 421375
 *******************************************************************************/
package org.eclipse.core.internal.expressions;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;

import org.w3c.dom.Element;

import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ICountable;
import org.eclipse.core.expressions.IIterable;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;

public class Expressions {

	/**
	 * Cache to optimize instanceof computation. Weak Map of Class-&gt;Map(String, Boolean). Avoid
	 * conflicts caused by multiple classloader contributions with the same class name. It's a rare
	 * occurrence but is supported by the OSGi classloader.
	 */
	private static WeakHashMap<Class<?>, Map<String, Boolean>> fgKnownClasses;

	/**
	 * Cache to optimize loading of classes for evaluation of adapt expressions. Keys are class
	 * loaders. Values are sets of qualified class names that the corresponding class loader was
	 * not able to find.
	 */
	private static WeakHashMap<ClassLoader, Set<String>> fgNotFoundClasses;

	/* debugging flag to enable tracing */
	public static final boolean TRACING= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.core.expressions/tracePropertyResolving")); //$NON-NLS-1$ //$NON-NLS-2$


	private Expressions() {
		// no instance
	}

	public static boolean isInstanceOf(Object element, String type) {
		// null isn't an instanceof of anything.
		if (element == null)
			return false;
		return isSubtype(element.getClass(), type);
	}

	private static synchronized boolean isSubtype(Class<?> clazz, String type) {
		WeakHashMap<Class<?>, Map<String, Boolean>> knownClassesMap= getKnownClasses();
		Map<String, Boolean> nameMap = knownClassesMap.get(clazz);
		if (nameMap != null) {
			Object obj = nameMap.get(type);
			if (obj != null)
				return ((Boolean)obj).booleanValue();
		}
		if (nameMap == null) {
			nameMap = new HashMap<>();
			knownClassesMap.put(clazz, nameMap);
		}
		boolean isSubtype = uncachedIsSubtype(clazz, type);
		nameMap.put(type, isSubtype ? Boolean.TRUE : Boolean.FALSE);
		return isSubtype;
	}

	/**
	 * Loads the given class using the given class loader. Uses {@link #fgNotFoundClasses} for
	 * performance.
	 *
	 * @param classLoader the class loader to use
	 * @param className the qualified name of the class
	 * @return the loaded class, or {@code null} if the class was not found
	 */
	static Class<?> loadClass(ClassLoader classLoader, String className) {
		/*
		 * Class.forName is pretty slow when it throws a ClassNotFoundException. Since expression
		 * evaluation is done very often, we use a cache of names of classes that failed to load.
		 */
		WeakHashMap<ClassLoader, Set<String>> cache;
		synchronized (Expressions.class) {
			cache = getNotFoundClasses();
			Set<String> classNames= cache.get(classLoader);
			if (classNames != null && classNames.contains(className)) {
				return null;
			}
		}

		try {
			return Class.forName(className, false, classLoader);
		} catch (ClassNotFoundException e) {
			synchronized (Expressions.class) {
				Set<String> classNames= cache.get(classLoader);
				if (classNames == null) {
					classNames= new HashSet<>();
					cache.put(classLoader, classNames);
				}
				classNames.add(className);
			}
		}
		return null;
	}

	private static WeakHashMap<Class<?>, Map<String, Boolean>> getKnownClasses() {
		createClassCaches();
		return fgKnownClasses;
	}

	private static WeakHashMap<ClassLoader, Set<String>> getNotFoundClasses() {
		createClassCaches();
		return fgNotFoundClasses;
	}

	private static void createClassCaches() {
		if (fgKnownClasses == null) {
			fgKnownClasses= new WeakHashMap<>();
			fgNotFoundClasses = new WeakHashMap<>();
			BundleContext bundleContext= ExpressionPlugin.getDefault().getBundleContext();
			BundleListener listener= (BundleEvent event) -> {
				// Invalidate the caches if any of the bundles is stopped
				if (event.getType() == BundleEvent.STOPPED) {
					synchronized (Expressions.class) {
						fgKnownClasses.clear();
						fgNotFoundClasses.clear();
					}
				}
			};
			ExpressionPlugin.fgBundleListener = listener;
			bundleContext.addBundleListener(listener);
		}
	}

	public static boolean uncachedIsSubtype(Class<?> clazz, String type) {
		if (clazz.getName().equals(type))
			return true;
		Class<?> superClass= clazz.getSuperclass();
		if (superClass != null && uncachedIsSubtype(superClass, type))
			return true;
		Class<?>[] interfaces= clazz.getInterfaces();
		for (Class<?> interfaze : interfaces) {
			if (uncachedIsSubtype(interfaze, type))
				return true;
		}
		return false;
	}

	public static void checkAttribute(String name, String value) throws CoreException {
		if (value == null) {
			throw new CoreException(new ExpressionStatus(
				ExpressionStatus.MISSING_ATTRIBUTE,
				Messages.format(ExpressionMessages.Expression_attribute_missing, name)));
		}
	}

	public static void checkAttribute(String name, String value, String[] validValues) throws CoreException {
		checkAttribute(name, value);
		for (String validValue : validValues) {
			if (value.equals(validValue))
				return;
		}
		throw new CoreException(new ExpressionStatus(
			ExpressionStatus.WRONG_ATTRIBUTE_VALUE,
			Messages.format(ExpressionMessages.Expression_attribute_invalid_value, value)));
	}

	public static void checkCollection(Object var, Expression expression) throws CoreException {
		if (var instanceof Collection)
			return;
		throw new CoreException(new ExpressionStatus(
			ExpressionStatus.VARIABLE_IS_NOT_A_COLLECTION,
			Messages.format(ExpressionMessages.Expression_variable_not_a_collection, expression.toString())));
	}

	public static void checkList(Object var, Expression expression) throws CoreException {
		if (var instanceof List)
			return;
		throw new CoreException(new ExpressionStatus(
			ExpressionStatus.VARIABLE_IS_NOT_A_LIST,
			Messages.format(ExpressionMessages.Expression_variable_not_a_list, expression.toString())));
	}

	/**
	 * Converts the given variable into an <code>IIterable</code>. If a corresponding adapter can't be found an
	 * exception is thrown. If the corresponding adapter isn't loaded yet, <code>null</code> is returned.
	 *
	 * @param var the variable to turn into an <code>IIterable</code>
	 * @param expression the expression referring to the variable
	 *
	 * @return the <code>IIterable</code> or <code>null</code> if a corresponding adapter isn't loaded yet
	 *
	 * @throws CoreException if the var can't be adapted to an <code>IIterable</code>
	 */
	public static IIterable<?> getAsIIterable(Object var, Expression expression) throws CoreException {
		if (var instanceof IIterable) {
			return (IIterable<?>)var;
		} else {
			IAdapterManager manager= Platform.getAdapterManager();
			IIterable<?> result= manager.getAdapter(var, IIterable.class);
			if (result != null)
				return result;

			if (manager.queryAdapter(var, IIterable.class.getName()) == IAdapterManager.NOT_LOADED)
				return null;

			throw new CoreException(new ExpressionStatus(
				ExpressionStatus.VARIABLE_IS_NOT_A_COLLECTION,
				Messages.format(ExpressionMessages.Expression_variable_not_iterable, expression.toString())));
		}
	}

	/**
	 * Converts the given variable into an <code>ICountable</code>. If a corresponding adapter can't be found an
	 * exception is thrown. If the corresponding adapter isn't loaded yet, <code>null</code> is returned.
	 *
	 * @param var the variable to turn into an <code>ICountable</code>
	 * @param expression the expression referring to the variable
	 *
	 * @return the <code>ICountable</code> or <code>null</code> if a corresponding adapter isn't loaded yet
	 *
	 * @throws CoreException if the var can't be adapted to an <code>ICountable</code>
	 */
	public static ICountable getAsICountable(Object var, Expression expression) throws CoreException {
		if (var instanceof ICountable) {
			return (ICountable)var;
		} else {
			IAdapterManager manager= Platform.getAdapterManager();
			ICountable result= manager.getAdapter(var, ICountable.class);
			if (result != null)
				return result;

			if (manager.queryAdapter(var, ICountable.class.getName()) == IAdapterManager.NOT_LOADED)
				return null;

			throw new CoreException(new ExpressionStatus(
				ExpressionStatus.VARIABLE_IS_NOT_A_COLLECTION,
				Messages.format(ExpressionMessages.Expression_variable_not_countable, expression.toString())));
		}
	}

	public static boolean getOptionalBooleanAttribute(IConfigurationElement element, String attributeName) {
		String value= element.getAttribute(attributeName);
		if (value == null)
			return false;
		return Boolean.valueOf(value).booleanValue();
	}

	public static boolean getOptionalBooleanAttribute(Element element, String attributeName) {
		String value= element.getAttribute(attributeName);
		if (value.isEmpty())
			return false;
		return Boolean.valueOf(value).booleanValue();
	}

	//---- Argument parsing --------------------------------------------

	public static final Object[] EMPTY_ARGS= new Object[0];

	public static Object[] getArguments(IConfigurationElement element, String attributeName) throws CoreException {
		String args= element.getAttribute(attributeName);
		if (args != null) {
			return parseArguments(args);
		} else {
			return EMPTY_ARGS;
		}
	}

	public static Object[] getArguments(Element element, String attributeName) throws CoreException {
		String args= element.getAttribute(attributeName);
		if (!args.isEmpty()) {
			return parseArguments(args);
		} else {
			return EMPTY_ARGS;
		}
	}

	public static Object[] parseArguments(String args) throws CoreException {
		List<Object> result= new ArrayList<>();
		int start= 0;
		int comma;
		while ((comma= findNextComma(args, start)) != -1) {
			result.add(convertArgument(args.substring(start, comma).trim()));
			start= comma + 1;
		}
		result.add(convertArgument(args.substring(start).trim()));
		return result.toArray();
	}

	private static int findNextComma(String str, int start) throws CoreException {
		boolean inString= false;
		for (int i= start; i < str.length(); i++) {
			char ch= str.charAt(i);
			if (ch == ',' && ! inString)
				return i;
			if (ch == '\'') {
				if (!inString) {
					inString= true;
				} else {
					if (i + 1 < str.length() && str.charAt(i + 1) == '\'') {
						i++;
					} else {
						inString= false;
					}
				}
			} else if (ch == ',' && !inString) {
				return i;
			}
		}
		if (inString)
			throw new CoreException(new ExpressionStatus(
				ExpressionStatus.STRING_NOT_TERMINATED,
				Messages.format(ExpressionMessages.Expression_string_not_terminated, str)));

		return -1;
	}

	public static Object convertArgument(String arg) throws CoreException {
		if (arg == null) {
			return null;
		} else if (arg.isEmpty()) {
			return arg;
		} else if (arg.charAt(0) == '\'' && arg.charAt(arg.length() - 1) == '\'') {
			return unEscapeString(arg.substring(1, arg.length() - 1));
		} else if ("true".equals(arg)) { //$NON-NLS-1$
			return Boolean.TRUE;
		} else if ("false".equals(arg)) { //$NON-NLS-1$
			return Boolean.FALSE;
		} else if (arg.indexOf('.') != -1) {
			try {
				return Float.valueOf(arg);
			} catch (NumberFormatException e) {
				return arg;
			}
		} else {
			try {
				return Integer.valueOf(arg);
			} catch (NumberFormatException e) {
				return arg;
			}
		}
	}

	public static String unEscapeString(String str) throws CoreException {
		StringBuilder result= new StringBuilder();
		for (int i= 0; i < str.length(); i++) {
			char ch= str.charAt(i);
			if (ch == '\'') {
				if (i == str.length() - 1 || str.charAt(i + 1) != '\'')
					throw new CoreException(new ExpressionStatus(
						ExpressionStatus.STRING_NOT_CORRECT_ESCAPED,
						Messages.format(ExpressionMessages.Expression_string_not_correctly_escaped, str)));
				result.append('\'');
				i++;
			} else {
				result.append(ch);
			}
		}
		return result.toString();
	}
}
