/*******************************************************************************
 * Copyright (c) 2010, 2014 Willink Transformations and others.
 * 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:
 *     E.D.Willink - initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.pivot.labels;

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

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.internal.labels.BooleanLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.DynamicEObjectImplLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.EAnnotationLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.EGenericTypeLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.ENamedElementLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.EObjectLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.EcoreURILabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.ElementIdLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.ExpressionInOCLLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.ModelLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.NameableLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.NumberLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.StringLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.TransformationInstanceLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.TypedModelInstanceLabelGenerator;
import org.eclipse.ocl.pivot.internal.labels.ValueLabelGenerator;
import org.eclipse.ocl.pivot.internal.plugin.LabelGeneratorRegistryReader;
import org.eclipse.ocl.pivot.labels.ILabelGenerator.Descriptor;

/**
 * DebugString supports generation of debug identification of objects, determining a name usuing
 * the following alternatives.
 * <br>The null object is identified as <null-Object>
 * <br>Implementers of IDebugString are identified by IDebugString.toDebugString();
 * <br>MethodCall registrations in DebugUtils are identified by MethodCall.invoke().
 * <br>Other objects are identified as <unknown-'class-name' 'object.toString()'>
 * <p>
 * MethodCall registrations may be made via registerInstanceMethod or registerStaticMethod.
 * <p>
 * A debug string may be obtained via DebugString.toDebug(object).
 * <p>
 * DebugString providers string formatters for simple classes such as String, Number, Boolean
 * and Ecore components such as EObject, Resource and ResourceSet.
 * <p>
 * User extensions should be registered prior to use. Beware that late registration can
 * give misleading results since in the absence of an exact MethodCall registration the
 * class hierarchy is search first for base classes then for instances for which there
 * is an exact MethodCall match. This result is then cached and so may occlude a late
 * registration.
 */
public class LabelGeneratorRegistry implements ILabelGenerator.Registry
{	
	public static class Global extends LabelGeneratorRegistry
	{
		private boolean initialized = false;
		
		public Global() {}
		
		public void initialize() {
			initialized = true;
			if (EcorePlugin.IS_ECLIPSE_RUNNING) {
				new LabelGeneratorRegistryReader(this).readRegistry();
			}
			else {
				initialize(this);
			}
		}

		@Override
		public @Nullable ILabelGenerator<?> get(@NonNull Class<?> labelledClass) {
			if (!initialized) {
				initialize();
			}
			return super.get(labelledClass);
		}

		@Override
		public @Nullable Object install(@NonNull Class<?> labelledClass, @NonNull Descriptor labelDescriptor) {
			if (!initialized) {
				initialize();
			}
			return super.install(labelledClass, labelDescriptor);
		}

		@Override
		public @Nullable Object install(@NonNull Class<?> labelledClass, @NonNull ILabelGenerator<?> labelGenerator) {
			if (!initialized) {
				initialize();
			}
			return super.install(labelledClass, labelGenerator);
		}

		@Override
		public void uninstall(@NonNull Class<?> labelledClass) {
			if (!initialized) {
				initialize();
			}
			super.uninstall(labelledClass);
		}
	}
	
	public static @NonNull String debugLabelFor(@NonNull Object object) {
		Map<ILabelGenerator.Option<?>, Object> options = new HashMap<ILabelGenerator.Option<?>, Object>();
		options.put(ILabelGenerator.Builder.SHOW_CLASS_SIMPLE_NAME, Boolean.TRUE);
		ILabelGenerator.Builder result = new DefaultLabelGeneratorBuilder(INSTANCE, object, options);
		result.buildLabelFor(object);
		return result.toString();
	}

	public static @NonNull LabelGeneratorRegistry init() {
		return new LabelGeneratorRegistry.Global();
	}

	public static void initialize(@NonNull ILabelGenerator.Registry registry) {
		BooleanLabelGenerator.initialize(registry);
		DynamicEObjectImplLabelGenerator.initialize(registry);
		EAnnotationLabelGenerator.initialize(registry);
		EGenericTypeLabelGenerator.initialize(registry);
		ENamedElementLabelGenerator.initialize(registry);
		EObjectLabelGenerator.initialize(registry);
		EcoreURILabelGenerator.initialize(registry);
		ElementIdLabelGenerator.initialize(registry);
		ExpressionInOCLLabelGenerator.initialize(registry);
		ModelLabelGenerator.initialize(registry);
		NameableLabelGenerator.initialize(registry);
		NumberLabelGenerator.initialize(registry);
		StringLabelGenerator.initialize(registry);
		TransformationInstanceLabelGenerator.initialize(registry);
		TypedModelInstanceLabelGenerator.initialize(registry);
		ValueLabelGenerator.initialize(registry);
	}

	protected final @Nullable ILabelGenerator.Registry delegate;
	private final @NonNull Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();
	
	/**
	 * Construct a registry that resolves label generators locally.
	 */
	private LabelGeneratorRegistry() {
		this.delegate = null;
	}
	
	/**
	 * Construct a registry that resolves label generators locally when possible
	 * but which delegates to delegate otherwise.
	 */
	public LabelGeneratorRegistry(@Nullable ILabelGenerator.Registry delegate) {
		this.delegate = delegate;
	}

	@Override
	public <T> void buildLabelFor(@NonNull ILabelGenerator.Builder s, @Nullable T labelledObject) {
		if (labelledObject == null) {
			s.appendString("<null-Object>");
			return;
		}
		Boolean showClassName = s.getOption(ILabelGenerator.Builder.SHOW_CLASS_NAME);
		if ((showClassName != null) && (showClassName == Boolean.TRUE)) {
			s.appendString(labelledObject.getClass().getName());
			s.appendString(" ");
		}
		else {
			Boolean showClassSimpleName = s.getOption(ILabelGenerator.Builder.SHOW_CLASS_SIMPLE_NAME);
			if ((showClassSimpleName != null) && (showClassSimpleName == Boolean.TRUE)) {
				s.appendString(labelledObject.getClass().getSimpleName());
				s.appendString(" ");
			}			
		}
		if (labelledObject instanceof EObject) {
			EObject eContainer = ((EObject)labelledObject).eContainer();
			if (eContainer != null) {
				String showQualifier = s.getOption(ILabelGenerator.Builder.SHOW_QUALIFIER);
				if (showQualifier != null) {
					buildLabelFor(s, eContainer);
					if (s.toString().length() > 0) {
						s.appendString(showQualifier);
					}
				}
			}
		}
		if (labelledObject instanceof ILabelGenerator.Self) {
			((ILabelGenerator.Self)labelledObject).buildLabel(s);
			return;
		}
		buildSubLabelFor(s, labelledObject);
	}

	@Override
	public <T> void buildSubLabelFor(@NonNull ILabelGenerator.Builder labelBuilder, @Nullable T labelledObject) {
		if (labelledObject == null) {
			labelBuilder.appendString("<null-Object>");
			return;
		}
		@SuppressWarnings("null")@NonNull Class<? extends Object> labelledObjectClass = labelledObject.getClass();
		ILabelGenerator<?> labelGenerator = get(labelledObjectClass);
		if (labelGenerator == null) {
			labelGenerator = getLabelGenerator(labelledObjectClass);
			if (labelGenerator != null)
				install(labelledObjectClass, labelGenerator);
		}
		if (labelGenerator != null) {
			@SuppressWarnings("unchecked")
			ILabelGenerator<T> castLabelGenerator = (ILabelGenerator<T>) labelGenerator;
			castLabelGenerator.buildLabelFor(labelBuilder, labelledObject);
			return;
		}
		else {
			getLabelGenerator(labelledObjectClass);		// Debugging
		}
		labelBuilder.appendString("<unknown-");
		labelBuilder.appendString(labelledObjectClass.getSimpleName());
		labelBuilder.appendString(" ");
		labelBuilder.appendString(labelledObject.toString());
		labelBuilder.appendString(">");
	}
	
  	public @NonNull ILabelGenerator.Builder createDefaultLabelBuilder(@Nullable Object labelledObject, @Nullable Map<ILabelGenerator.Option<?>, Object> options) {
  		return new DefaultLabelGeneratorBuilder(this, labelledObject, options);
  	}
    
	@Override
	public @Nullable ILabelGenerator<?> get(@NonNull Class<?> labelledClass) {
		Object object;
		synchronized(map) {
			object = map.get(labelledClass);
			if (object instanceof ILabelGenerator.Descriptor) {
				object = ((ILabelGenerator.Descriptor)object).getLabelGenerator();
				map.put(labelledClass, object);
			}
		}
		if (object != null) {
			return (ILabelGenerator<?>)object;
		}
		else if (delegate != null) {
			return delegate.get(labelledClass);			
		}
		else {
			return null;
		}
	}

	protected @Nullable ILabelGenerator<?> getLabelGenerator(@NonNull Class<?> cls) {
		for (Class<?> sCls = cls; sCls != null; sCls = sCls.getSuperclass()) {
			ILabelGenerator<?> labelGenerator = get(sCls);
			if (labelGenerator != null)
				return labelGenerator;	
		}
		for (@SuppressWarnings("null")@NonNull Class<?> iCls : cls.getInterfaces()) {
			ILabelGenerator<?> labelGenerator = get(iCls);
			if (labelGenerator != null)
				return labelGenerator;	
		}
		for (@SuppressWarnings("null")@NonNull Class<?> iCls : cls.getInterfaces()) {
			ILabelGenerator<?> labelGenerator = getLabelGenerator(iCls);
			if (labelGenerator != null)
				return labelGenerator;	
		}
		Class<?> sCls = cls.getSuperclass();
		if (sCls != null)
			return getLabelGenerator(sCls);
		return null;
	}

	@Override
	public @Nullable Object install(@NonNull Class<?> labelledClass, @NonNull Descriptor labelDescriptor) {
		synchronized(map) {
			return map.put(labelledClass, labelDescriptor);
		}
	}

	@Override
	public @Nullable Object install(@NonNull Class<?> labelledClass, @NonNull ILabelGenerator<?> labelGenerator) {
		synchronized(map) {
			return map.put(labelledClass, labelGenerator);
		}
	}

	@Override
	public @NonNull String labelFor(@Nullable Object labelledObject) {
		ILabelGenerator.Builder labelBuilder = createDefaultLabelBuilder(labelledObject, null);
		labelBuilder.buildLabelFor(labelledObject);
		return labelBuilder.toString();
	}

	@Override
	public @NonNull String labelFor(@Nullable Object labelledObject, @Nullable Map<ILabelGenerator.Option<?>, Object> options) {
		ILabelGenerator.Builder labelBuilder = createDefaultLabelBuilder(labelledObject, options);
		labelBuilder.buildLabelFor(labelledObject);
		return labelBuilder.toString();
	}

	@Override
	public void uninstall(@NonNull Class<?> labelledClass) {
		synchronized(map) {
			for (Class<?> aClass : new ArrayList<Class<?>>(map.keySet()))
			{
				if (labelledClass.isAssignableFrom(aClass)) {
					map.remove(aClass);
				}
			}
		}
	}
}