/*=============================================================================#
 # Copyright (c) 2009, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.ltk.core;

import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


@NonNullByDefault
public class AdapterFactory {
	
	
	private static final String ADAPTER_ELEMENT_NAME= "adapter"; //$NON-NLS-1$
	
	private static final String MODEL_TYPE_ID_ATTRIBUTE_NAME= "modelTypeId"; //$NON-NLS-1$
	private static final String TYPE_ATTRIBUTE_NAME= "type"; //$NON-NLS-1$
	private static final String CLASS_ATTRIBUTE_NAME= "class"; //$NON-NLS-1$
	
	
	private static interface AdapterContribution {
		
		<T> @Nullable T getAdapter(final String modelTypeId, final Class<T> adapterType);
		
	}
	
	private static class ClassContribution implements AdapterContribution {
		
		private @Nullable IConfigurationElement configurationElement;
		
		public ClassContribution(final IConfigurationElement contributionElement) {
			this.configurationElement= contributionElement;
		}
		
		@Override
		@SuppressWarnings("unchecked")
		public <T> @Nullable T getAdapter(final String modelTypeId, final Class<T> adapterType) {
			final IConfigurationElement configurationElement= this.configurationElement;
			if (configurationElement != null) {
				try {
					return (T) configurationElement.createExecutableExtension(CLASS_ATTRIBUTE_NAME);
				}
				catch (final CoreException e) {
					this.configurationElement= null;
					LtkCorePlugin.log(new Status(IStatus.ERROR, LtkCorePlugin.BUNDLE_ID, 0,
							NLS.bind("An error occurred when loading adapter class for model ''{0}''.", modelTypeId),
							e ));
				}
			}
			return null;
		}
		
	}
	
	private static class FactoryContribution implements AdapterContribution {
		
		private @Nullable IConfigurationElement configurationElement;
		private @Nullable IAdapterFactory factory;
		
		public FactoryContribution(final IConfigurationElement configurationElement) {
			this.configurationElement= configurationElement;
		}
		
		@Override
		public <T> @Nullable T getAdapter(final String modelTypeId, final Class<T> adapterType) {
			IAdapterFactory factory;
			synchronized (this) {
				factory = this.factory;
				final IConfigurationElement configurationElement;
				if (factory == null && (configurationElement= this.configurationElement) != null) {
					try {
						factory= (IAdapterFactory)configurationElement.createExecutableExtension(CLASS_ATTRIBUTE_NAME);
						this.factory= factory;
					}
					catch (final CoreException e) {
						this.configurationElement= null;
						LtkCorePlugin.log(new Status(IStatus.ERROR, LtkCorePlugin.BUNDLE_ID, 0,
								NLS.bind("An error occurred when loading adapter factory for model ''{0}''.", modelTypeId),
								e ));
					}
				}
			}
			if (factory != null) {
				return factory.getAdapter(modelTypeId, adapterType);
			}
			return null;
		}
		
	}
	
	
	private final String extensionPointId;
	
	private final Map<String, Map<String, AdapterContribution>> map= new IdentityHashMap<>();
	
	
	public AdapterFactory(final String extensionPointId) {
		this.extensionPointId= extensionPointId;
		load();
	}
	
	
	private void load() {
		final IExtensionRegistry extensionRegistry= Platform.getExtensionRegistry();
		final IConfigurationElement[] elements= extensionRegistry.getConfigurationElementsFor(
				this.extensionPointId);
		for (final IConfigurationElement contributionElement : elements) {
			String modelTypeId= contributionElement.getAttribute(
					MODEL_TYPE_ID_ATTRIBUTE_NAME);
			if (modelTypeId != null) {
				modelTypeId= modelTypeId.intern();
				Map<String, AdapterContribution> map= this.map.get(modelTypeId);
				if (map == null) {
					map= new HashMap<>();
					this.map.put(modelTypeId, map);
				}
				final IConfigurationElement[] adapterElements= contributionElement.getChildren();
				for (final IConfigurationElement adapterElement : adapterElements) {
					if (adapterElement.getName().equals(ADAPTER_ELEMENT_NAME)) {
						final String type= adapterElement.getAttribute(TYPE_ATTRIBUTE_NAME);
						if (type != null) {
							if (contributionElement.getName().equals("adapterClass")) { //$NON-NLS-1$
								map.put(type, new ClassContribution(contributionElement));
							}
							else if (contributionElement.getName().equals("adapterFactory")) { //$NON-NLS-1$
								map.put(type, new FactoryContribution(contributionElement));
							}
						}
					}
				}
			}
		}
	}
	
	public <T> @Nullable T get(final String modelTypeId, final Class<T> adapterType) {
		AdapterContribution contribution;
		synchronized (this.map) {
			final Map<String, AdapterContribution> map= this.map.get(modelTypeId);
			if (map == null) {
				return null;
			}
			contribution= map.get(adapterType.getName());
		}
		return (contribution != null) ? contribution.getAdapter(modelTypeId, adapterType) : null;
	}
	
}
