/*******************************************************************************
 * Copyright (c) 2013, 2018 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.examples.codegen.genmodel;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.codegen.ecore.generator.Generator;
import org.eclipse.emf.codegen.ecore.generator.GeneratorAdapterFactory;
import org.eclipse.emf.codegen.ecore.genmodel.generator.GenModelGeneratorAdapter;
import org.eclipse.emf.codegen.jet.JETEmitter;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.dynamic.JavaFileUtil;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleWiring;

//
//	Overridden to allow static templates to be invoked.
//
@Deprecated		/* @deprecated temporary workaround for Bug 543870 */
public class OCLGenModelGeneratorAdapter extends GenModelGeneratorAdapter
{
	/**
	 * TemplateClassLoader overrides URLClassLoader to provide the option to return null
	 * from loadTemplateClass if the explicitly requested class is not found. Other, referenced
	 * classes, requested via loadClass fall-back on the classLoader if the urls access fails.
	 *
	 * This class and OCLGenModelGeneratorAdapter can be deleted if Bug 543870 fix is available.
	 */
	protected static class TemplateClassLoader extends URLClassLoader
	{
		/**
		 * The ClassLoader to be used to load not-nested classes referenced from a template class.
		 */
		private final @NonNull ClassLoader classLoader;

		/**
		 * The root (qualified, but not-nested) template class names handled by this TemplateClassLoader.
		 */
		private final @NonNull Set<@NonNull String> templateClassNames = new HashSet<>();

		public TemplateClassLoader(@NonNull URL url, @NonNull ClassLoader classLoader) {
			super(new URL[]{url}, null);		// Suppress default fall-back to parent.
			assert url != null;
			assert classLoader != null;
			this.classLoader =  classLoader;
		}

		/**
		 * Re-implement to load any nested class of any of the templateClassNames direct from its class file.
		 * Other classes are loaded by the normal classLoader.
		 */
		@Override
		protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
			int index = className.indexOf("$");
			String rootClassName = index >= 0 ? className.substring(0, index) : className;
			if (templateClassNames.contains(rootClassName)) {
				return super.loadClass(className, resolve);
			}
			else {
				return classLoader.loadClass(className);
			}
		}

		/**
		 * Load and return the templateClassName using the templateClassPath configuring the template
		 * class loader to also load the templateClassName's nested classes. Returns null if no
		 * template class found. This allows a variety of explicit template class paths to be tried
		 * before a fall back to the normal class loader.
		 */
		public Class<?> loadTemplateClass(@NonNull String templateClassName) throws ClassNotFoundException {
			assert templateClassName != null;
			Class<?> templateClass = super.loadClass(templateClassName, true);
			if (templateClass != null) {
				templateClassNames.add(templateClassName);
			}
			return templateClass;
		}
	}

	/**
	 * Cached sorted standalone classpath entries.
	 */
	private @NonNull String[] sortedClasspath = null;

	/**
	 * Map from templateClassPath to the TemplatePathClassLoader that loads direct from the class file. These classes
	 * remain loaded for the lifetime of this AbstractGeneratorAdapter. i.e. Re-open the GenModel
	 * editor to respond to changed classes.
	 */
	private Map<@NonNull File, @NonNull TemplateClassLoader> templatePath2classLoader = null;

	public OCLGenModelGeneratorAdapter(@NonNull GeneratorAdapterFactory generatorAdapterFactory) {
		super(generatorAdapterFactory);
	}

	/**
	 * Return the java.class.path entry that resolves absoluteTemplateName references.
	 * This is only useful when running standalone. When using OSGI, the appropriate bundle-specific
	 * class loader should be used instead.
	 */
	protected @Nullable String getStandaloneTemplateClassPath(@NonNull String workspaceName) {
		URI absoluteTemplateURI = EcorePlugin.resolvePlatformResourcePath(workspaceName);
		if (absoluteTemplateURI == null) {
			return null;
		}
		if (absoluteTemplateURI.isArchive()) {
			absoluteTemplateURI = URI.createURI(absoluteTemplateURI.authority() + absoluteTemplateURI.path());
		}
		String absoluteTemplateName = absoluteTemplateURI.isFile() ? absoluteTemplateURI.toFileString() : absoluteTemplateURI.toString();
		if (absoluteTemplateName == null) {			// Never happens
			return null;
		}
		if (sortedClasspath == null) {
			sortedClasspath = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
			Arrays.sort(sortedClasspath);
		}
		int matchIndex  = Arrays.binarySearch(sortedClasspath, absoluteTemplateName);
		if (matchIndex >= 0) {          // Never happens - unless the templateDirectory is actually the bin folder
			return sortedClasspath[matchIndex];
		}
		int insertionPoint = -(matchIndex + 1);  //  classpath[insertionPoint-1] < absoluteTemplateName < classpath[insertionPoint]
		if (insertionPoint <= 0) {
			return sortedClasspath[0];
		}
		if (insertionPoint >= sortedClasspath.length) {
			return sortedClasspath[sortedClasspath.length-1];
		}
		String prevClassElement = sortedClasspath[insertionPoint-1];
		String nextClassElement = sortedClasspath[insertionPoint];
		int prevLength = prevClassElement.length();
		int nextLength = nextClassElement.length();
		int absoluteTemplateNameLength = absoluteTemplateName.length();
		for (int i = 0; i < absoluteTemplateNameLength; i++) {
			char c = absoluteTemplateName.charAt(i);
			if (i >= prevLength) {          // prevClassElement is prefix
				return prevClassElement;
			}
			if (i >= nextLength) {          // nextClassElement is prefix
				return nextClassElement;
			}
			char prevC = prevClassElement.charAt(i);
			if (prevC != c) {
				return nextClassElement;
			}
			char nextC = nextClassElement.charAt(i);
			if (nextC != c) {
				return prevClassElement;
			}
		}
		return prevClassElement;          // Never happens, unless there are duplicates in which case nextClassElement is the same.
	}

	/**
	 * If {@link Generator.Options#dynamicTemplates dynamic templates} are not being used,
	 * attempts to set the emitter to use an existing, precompiled template class
	 * that has the given method name and argument types.
	 * @since 2.5
	 */
	@Override
	protected void setStaticTemplateClass(JETEmitter jetEmitter, String className, String methodName, Class<?>[] arguments)
	{
		assert className != null;
		if (!getGenerator().getOptions().dynamicTemplates)
		{
			Class<?> templateClass = null;
			List<String> userTemplatePath = getUserTemplatePath();	// Omit the built-in emf.codegen.ecore to avoid caching; go direct to the fallback
			if (!userTemplatePath.isEmpty()) {
				templateClass = getStaticUserTemplateClass(userTemplatePath, className);
			}
			try {
				if (templateClass == null) {							// Fall-back load as an ordinary class
					templateClass = getClass().getClassLoader().loadClass(className);
				}
				Method emitterMethod = templateClass.getDeclaredMethod(methodName, arguments);
				jetEmitter.setMethod(emitterMethod);
			}
			catch (Exception exception)
			{
				// It's okay for there not be a precompiled template, so fail quietly.
			}
		}
	}

	public @Nullable Class<?> getStaticUserTemplateClass(@NonNull List<String> userTemplatePath, @NonNull String className) {
		if (templatePath2classLoader == null) {
			templatePath2classLoader = new HashMap<>();
		}
		//
		//  Try to load the className direct from the classPath corresponding to each templatePath element,
		//
		for (String templateElement : userTemplatePath) {
			try {
				ClassLoader classLoader = getClass().getClassLoader();
				File templateClassPathFile = null;					// e.g. E:\...
				URI uri = URI.createURI(templateElement);
				if (uri.isPlatform()) {
					URI deresolveURI = uri.isPlatformResource() ? URI.createPlatformResourceURI("/", false) : URI.createPlatformPluginURI("/", false);
					URI workspaceURI = uri.deresolve(deresolveURI);
					String workspaceName = "/" + workspaceURI.toString();
					IWorkspaceRoot root = EcorePlugin.getWorkspaceRoot();
					if (root != null) {
						String projectName = workspaceURI.segment(0);
						Bundle bundle = Platform.getBundle(projectName);
						BundleWiring bundleWiring = ClassUtil.nonNullState(bundle.adapt(BundleWiring.class));
						classLoader = bundleWiring.getClassLoader();
						templateClassPathFile = JavaFileUtil.getOSGIClassPath(bundle);
					}
					else {
						String templateClassPath2 = getStandaloneTemplateClassPath(workspaceName);
						if (templateClassPath2 != null) {
							templateClassPathFile = new File(templateClassPath2);
						}
					}
				}
				else if (uri.isFile()) {
					templateClassPathFile = new File(uri.toString());
				}
				else {
					templateClassPathFile = new File(uri.toFileString());
				}
				if (templateClassPathFile != null) {
					TemplateClassLoader templatePathClassLoader = templatePath2classLoader.get(templateClassPathFile);
					if (templatePathClassLoader == null) {
						assert classLoader != null;
						String templateClassPathString = URI.createFileURI(templateClassPathFile.toString()).toString();		// e.g. file:/E:/...
						URL templateClassPathURL = new URL(templateClassPathFile.isFile() ? templateClassPathString : templateClassPathString + "/");	// e.g. file:/E:/... ...jar or .../bin/
						templatePathClassLoader = new TemplateClassLoader(templateClassPathURL, classLoader);
						templatePath2classLoader.put(templateClassPathFile, templatePathClassLoader);
					}
					return templatePathClassLoader.loadTemplateClass(className);
				}
			}
			catch (Exception e) {
				getClass();
				// If some template path attempt fails just move on to the next one.}
			}
		}
		return null;
	}
}
