/*******************************************************************************
 * Copyright (c) 2011, 2019 Willink Transformations and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     E.D.Willink - initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.pivot.internal.library;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.ElementExtension;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.Feature;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Stereotype;
import org.eclipse.ocl.pivot.TupleType;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.ids.TuplePartId;
import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager;
import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal;
import org.eclipse.ocl.pivot.internal.utilities.Technology;
import org.eclipse.ocl.pivot.library.LibraryFeature;
import org.eclipse.ocl.pivot.library.LibraryProperty;
import org.eclipse.ocl.pivot.library.UnsupportedOperation;
import org.eclipse.ocl.pivot.resource.ASResource;
import org.eclipse.ocl.pivot.util.DerivedConstants;

/**
 * ImplementationManager encapsulates the knowledge about known feature implementations.
 */
public class ImplementationManager
{
	private static final Logger logger = Logger.getLogger(ImplementationManager.class);

	protected final @NonNull EnvironmentFactoryInternal environmentFactory;
	protected final @NonNull Technology technology;
	private final @NonNull PivotMetamodelManager metamodelManager;

	/**
	 * ClassLoaders that may be able to load a library implementation.
	 */
	private List<@NonNull ClassLoader> classLoaders = null;

	public ImplementationManager(@NonNull EnvironmentFactoryInternal environmentFactory) {
		this.environmentFactory = environmentFactory;
		this.technology = environmentFactory.getTechnology();
		this.metamodelManager = environmentFactory.getMetamodelManager();
	}

	public void addClassLoader(@NonNull ClassLoader classLoader) {
		List<ClassLoader> classLoaders = getClassLoaders();
		if (!classLoaders.contains(classLoader)) {
			classLoaders.add(classLoader);
		}
	}

	public @NonNull List<@NonNull ClassLoader> getClassLoaders() {
		List<@NonNull ClassLoader> classLoaders2 = classLoaders;
		if (classLoaders2 == null) {
			classLoaders2 = classLoaders = new ArrayList<@NonNull ClassLoader>();
			ClassLoader classLoader = metamodelManager.getClass().getClassLoader();
			assert classLoader != null;
			classLoaders2.add(classLoader);
		}
		return classLoaders2;
	}

	/*	protected @NonNull LibraryOperation getOperationImplementation(@NonNull Operation operation) {
		LibraryFeature implementation = metamodelManager.getImplementation(operation);
		String implementationClassName = operation.getImplementationClass();
		if (implementationClassName != null) {
			if (!implementation.getClass().getName().equals(implementationClassName)) {
				try {
					implementation = loadImplementation(operation);
					if (implementation instanceof LibraryOperation) {
						return (LibraryOperation)implementation;
					}
				} catch (Exception e) {
					logger.error("Failed to load implementation of '" + operation + "'", e);
				}
				return UnsupportedOperation.INSTANCE;
			}
		}
		ExpressionInOCL specification = metamodelManager.getBodyExpression(operation);
		if (specification != null) {
			return new ConstrainedOperation(specification);
		}
		return UnsupportedOperation.INSTANCE;
	} */

	// See Bug 458394 for the need for the asNavigationExp argument.
	public @NonNull LibraryProperty getPropertyImplementation(@Nullable Element asNavigationExp, @Nullable Object sourceValue, @NonNull Property property) {
		LibraryFeature implementation = property.getImplementation();
		String implementationClassName = property.getImplementationClass();
		if (implementationClassName != null) {
			if ((implementation == null) || !implementation.getClass().getName().equals(implementationClassName)) {
				try {
					implementation = loadImplementation(property);
					if (implementation instanceof LibraryProperty) {
						return (LibraryProperty) implementation;
					}
				} catch (Exception e) {
					logger.error("Failed to load implementation of '" + property + "'", e);
				}
				return UnsupportedOperation.INSTANCE;
			}
		}
		Type type = property.getType();
		if ((type instanceof Stereotype) && property.getName().startsWith(DerivedConstants.STEREOTYPE_EXTENSION_PREFIX)) {
			return technology.createExtensionPropertyImplementation(environmentFactory, property);
		}
		//		if (property.getOwningType() instanceof Stereotype) {
		//			return new BaseProperty(property);
		//		}
		ExpressionInOCL specification = metamodelManager.getDefaultExpression(property);
		if (property.isIsDerived() && (specification != null)) {
			return new ConstrainedProperty(property);
		}
		Property opposite = property.getOpposite();
		if ((opposite != null) && opposite.isIsComposite()) {
			if (property.eContainer() instanceof Stereotype) {
				return technology.createBasePropertyImplementation(environmentFactory, property);
			}
			if (type != null) {
				EObject eTarget = opposite.getESObject();
				if (eTarget instanceof EReference) {
					return new CompositionProperty((EReference) eTarget, opposite.getPropertyId());
				}
				if (eTarget != null) {
					Resource resource = opposite.eResource();
					if (resource instanceof ASResource) {
						ASResource asResource = (ASResource)resource;
						EReference eReference = asResource.getASResourceFactory().getEReference(asResource, eTarget);
						if (eReference != null) {
							return new CompositionProperty(eReference, opposite.getPropertyId());
						}
					}
				}
				/*				eTarget = type.getETarget();
				if (eTarget != null) {
					EClass eOwningClass = eTarget.eClass();
					EClass eOwnedClass = property.getOwningType().getETarget().eClass();
					EList<EStructuralFeature> ownerStructuralFeatures = eOwningClass.getEAllStructuralFeatures();
					EList<EStructuralFeature> ownedStructuralFeatures = eOwnedClass.getEAllStructuralFeatures();
					EStructuralFeature eFeature = EcoreUtils.getNamedElement(ownerStructuralFeatures, opposite.getName());
					if (eFeature instanceof EReference) {
						return new CompositionProperty((EReference) eFeature, opposite.getPropertyId());
					}
				} */
			}
		}
		if (property.isIsImplicit()) {
			return new ImplicitNonCompositionProperty(property);
		}
		if (property.getOwningClass() instanceof TupleType) {
			TupleType tupleType = (TupleType)property.getOwningClass();
			String name = property.getName();
			assert name != null;
			TuplePartId tuplePartId = tupleType.getTypeId().getPartId(name);
			assert tuplePartId != null;
			return new TuplePartProperty(tuplePartId);
		}
		if (property.isIsStatic()) {
			return new StaticProperty(property);
		}
		if ((property.getOwningClass() instanceof ElementExtension)			// direct access to extension property
				|| (property.getOwningClass() instanceof Stereotype)) {			// indirect access from a Stereotype operation
			return technology.createStereotypePropertyImplementation(environmentFactory, property);
		}
		return technology.createExplicitNavigationPropertyImplementation(environmentFactory, asNavigationExp, sourceValue, property);
	}

	public void dispose() {
		classLoaders = null;
	}

	/**
	 * Return the implementation of a feature.
	 *
	 * @param feature to be implemented.
	 * @return the implementation, or null if the feature has no implementation
	 * as is the case for a normal model feature
	 * @throws ClassNotFoundException if the implementation class realising
	 * the implementation is not loadable
	 * @throws NoSuchFieldException if the implementation class realising
	 * the implementation does not provide a static INSTANCE field
	 * @throws SecurityException if the implementation class is not accessible
	 * @throws IllegalAccessException if the implementation class is not accessible
	 * @throws IllegalArgumentException if the implementation class is not accessible
	 */
	public @Nullable LibraryFeature loadImplementation(@NonNull Feature feature) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		LibraryFeature implementation = feature.getImplementation();
		if (implementation == null) {
			String implementationClassName = feature.getImplementationClass();
			if (implementationClassName != null) {
				Class<?> theClass = null;
				ClassLoader featureClassLoader = feature.getClass().getClassLoader();
				if (featureClassLoader != null) {
					addClassLoader(featureClassLoader);
				}
				ClassNotFoundException e = null;
				for (@NonNull ClassLoader classLoader : getClassLoaders()) {
					try {
						theClass = classLoader.loadClass(implementationClassName);
						e = null;
						break;
					} catch (ClassNotFoundException e1) {
						if (e == null) {
							e = e1;
						}
					}
				}
				if (e != null) {
					throw e;
				}
				if (theClass != null) {
					Field field = theClass.getField("INSTANCE");
					implementation = (LibraryFeature) field.get(null);
				}
			}
		}
		return implementation;
	}

	/**
	 * @since 1.18
	 */
	public @Nullable Class<?> loadImplementation(@NonNull Object context, @NonNull String className) throws ClassNotFoundException {
		Class<?> theClass = null;
		ClassLoader contextClassLoader = context.getClass().getClassLoader();
		if (contextClassLoader != null) {
			addClassLoader(contextClassLoader);
		}
		ClassNotFoundException e = null;
		for (@NonNull ClassLoader classLoader : getClassLoaders()) {
			try {
				theClass = classLoader.loadClass(className);
				e = null;
				break;
			} catch (ClassNotFoundException e1) {
				if (e == null) {
					e = e1;
				}
			}
		}
		if (e != null) {
			throw e;
		}
	//	if (theClass != null) {
	//		Field field = theClass.getField("INSTANCE");
	//		implementation = (LibraryFeature) field.get(null);
	//	}
		return theClass;
	}
}