/*******************************************************************************
 * Copyright (c) 2000, 2009 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
 *******************************************************************************/
package org.eclipse.core.internal.expressions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.expressions.IPropertyTester;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionDelta;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IRegistryChangeEvent;
import org.eclipse.core.runtime.IRegistryChangeListener;
import org.eclipse.core.runtime.Platform;

public class TypeExtensionManager implements IRegistryChangeListener {

	private String fExtensionPoint;

	/**
	 * Tells whether this class is in debug mode.
	 *
	 * @since 3.5
	 */
	private static boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.core.expressions/debug/TypeExtensionManager")); //$NON-NLS-1$//$NON-NLS-2$

	private static final String TYPE= "type"; //$NON-NLS-1$

	private static final IPropertyTester[] EMPTY_PROPERTY_TESTER_ARRAY= new IPropertyTester[0];

	private static final IPropertyTester NULL_PROPERTY_TESTER= new IPropertyTester() {
		@Override
		public boolean handles(String namespace, String property) {
			return false;
		}
		@Override
		public boolean isInstantiated() {
			return true;
		}
		@Override
		public boolean isDeclaringPluginActive() {
			return true;
		}
		@Override
		public IPropertyTester instantiate() throws CoreException {
			return this;
		}
		@Override
		public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
			return false;
		}
	};

	/*
	 * Map containing all already created type extension object.
	 */
	private Map<Class<?>, TypeExtension> fTypeExtensionMap;

	/*
	 * Table containing mapping of class name to configuration element
	 */
	private Map<String, List<IConfigurationElement>> fConfigurationElementMap;

	/*
	 * A cache to give fast access to the last 1000 method invocations.
	 */
	private PropertyCache fPropertyCache;


	public TypeExtensionManager(String extensionPoint) {
		Assert.isNotNull(extensionPoint);
		fExtensionPoint= extensionPoint;
		Platform.getExtensionRegistry().addRegistryChangeListener(this);
		initializeCaches();
	}

	public Property getProperty(Object receiver, String namespace, String method) throws CoreException  {
		return getProperty(receiver, namespace, method, false);
	}

	public synchronized Property getProperty(Object receiver, String namespace, String method, boolean forcePluginActivation) throws CoreException  {
		long start= 0;
		if (Expressions.TRACING)
			start= System.currentTimeMillis();

		// if we call a static method than the receiver is the class object
		Class<?> clazz= receiver instanceof Class ? (Class<?>)receiver : receiver.getClass();
		Property result= new Property(clazz, namespace, method);
		Property cached= fPropertyCache.get(result);
		if (cached != null) {
			if (cached.isValidCacheEntry(forcePluginActivation)) {
				if (Expressions.TRACING) {
					System.out.println("[Type Extension] - method " + //$NON-NLS-1$
						clazz.getName() + "#" + method + //$NON-NLS-1$
						" found in cache: " +  //$NON-NLS-1$
						(System.currentTimeMillis() - start) + " ms."); //$NON-NLS-1$
				}
				return cached;
			}
			// The type extender isn't loaded in the cached method but can be loaded
			// now. So remove method from cache and do the normal look up so that the
			// implementation class gets loaded.
			fPropertyCache.remove(cached);
		}
		TypeExtension extension= get(clazz);
		IPropertyTester extender= extension.findTypeExtender(this, namespace, method, receiver instanceof Class, forcePluginActivation);
		if (extender == TypeExtension.CONTINUE || extender == null) {
			Throwable t= null;
			if (DEBUG) {
				//XXX: more logging for https://bugs.eclipse.org/bugs/show_bug.cgi?id=239715 :
				t= new Throwable("forcePluginActivation: " + forcePluginActivation + ", receiver: " + receiver).fillInStackTrace(); //$NON-NLS-1$ //$NON-NLS-2$
			}

			throw new CoreException(new ExpressionStatus(
				ExpressionStatus.TYPE_EXTENDER_UNKOWN_METHOD,
				Messages.format(
					ExpressionMessages.TypeExtender_unknownMethod,
					new String[] {namespace + '.' + method, clazz.toString()}),
					t));
		}
		result.setPropertyTester(extender);
		fPropertyCache.put(result);
		if (Expressions.TRACING) {
			System.out.println("[Type Extension] - method " + //$NON-NLS-1$
				clazz.getName() + "#" + method + //$NON-NLS-1$
				" not found in cache: " +  //$NON-NLS-1$
				(System.currentTimeMillis() - start) + " ms."); //$NON-NLS-1$
		}
		return result;
	}

	/*
	 * This method doesn't need to be synchronized since it is called
	 * from withing the getProperty method which is synchronized
	 */
	/* package */ TypeExtension get(Class<?> clazz) {
		TypeExtension result= fTypeExtensionMap.get(clazz);
		if (result == null) {
			result= new TypeExtension(clazz);
			fTypeExtensionMap.put(clazz, result);
		}
		return result;
	}

	/*
	 * This method doesn't need to be synchronized since it is called
	 * from withing the getProperty method which is synchronized
	 */
	/* package */ IPropertyTester[] loadTesters(Class<?> type) {
		if (fConfigurationElementMap == null) {
			fConfigurationElementMap= new HashMap<>();
			IExtensionRegistry registry= Platform.getExtensionRegistry();
			IConfigurationElement[] ces= registry.getConfigurationElementsFor(
				ExpressionPlugin.getPluginId(),
				fExtensionPoint);
			for (IConfigurationElement config : ces) {
				String typeAttr= config.getAttribute(TYPE);
				List<IConfigurationElement> typeConfigs= fConfigurationElementMap.get(typeAttr);
				if (typeConfigs == null) {
					typeConfigs= new ArrayList<>();
					fConfigurationElementMap.put(typeAttr, typeConfigs);
				}
				typeConfigs.add(config);
			}
		}
		String typeName= type.getName();
		List<IConfigurationElement> typeConfigs= fConfigurationElementMap.get(typeName);
		if (typeConfigs == null)
			return EMPTY_PROPERTY_TESTER_ARRAY;
		else {
			IPropertyTester[] result= new IPropertyTester[typeConfigs.size()];
			for (int i= 0; i < result.length; i++) {
				IConfigurationElement config= typeConfigs.get(i);
				try {
					result[i]= new PropertyTesterDescriptor(config);
				} catch (CoreException e) {
					ExpressionPlugin.getDefault().getLog().log(e.getStatus());
					result[i]= NULL_PROPERTY_TESTER;
				}
			}
			fConfigurationElementMap.remove(typeName);
			return result;
		}
	}

	@Override
	public void registryChanged(IRegistryChangeEvent event) {
		IExtensionDelta[] deltas= event.getExtensionDeltas(ExpressionPlugin.getPluginId(), fExtensionPoint);
		if (deltas.length > 0) {
			initializeCaches();
		}
	}

	private synchronized void initializeCaches() {
		fTypeExtensionMap= new HashMap<>();
		fConfigurationElementMap= null;
		fPropertyCache= new PropertyCache(1000);
	}
}
