/*******************************************************************************
 * Copyright (c) 2003,2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.core.runtime.adaptor;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.eclipse.osgi.framework.adaptor.BundleData;
import org.eclipse.osgi.framework.adaptor.ClassLoaderDelegate;
import org.eclipse.osgi.framework.adaptor.core.*;
import org.eclipse.osgi.framework.internal.core.AbstractBundle;
import org.eclipse.osgi.framework.internal.core.Msg;
import org.eclipse.osgi.framework.internal.defaultadaptor.DefaultClassLoader;
import org.eclipse.osgi.framework.internal.defaultadaptor.DevClassPathHelper;
import org.eclipse.osgi.framework.log.FrameworkLogEntry;
import org.eclipse.osgi.framework.stats.ClassloaderStats;
import org.eclipse.osgi.framework.stats.ResourceBundleStats;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.*;

public class EclipseClassLoader extends DefaultClassLoader {
	private static String[] NL_JAR_VARIANTS = buildNLJarVariants(System.getProperties().getProperty("osgi.nl")); //$NON-NLS-1$
	// from Eclipse-AutoStart element value
	private boolean autoStart;
	// from Eclipse-AutoStart's "exceptions" attribute
	private String[] exceptions;
	
	public EclipseClassLoader(ClassLoaderDelegate delegate, ProtectionDomain domain, String[] classpath, ClassLoader parent, BundleData bundleData) {
		super(delegate, domain, classpath, parent, (org.eclipse.osgi.framework.internal.defaultadaptor.DefaultBundleData) bundleData);
		parseAutoStart(bundleData);
	}
	private void parseAutoStart(BundleData bundleData) {
		try {
			String automationHeader = (String) bundleData.getManifest().get(EclipseAdaptorConstants.ECLIPSE_AUTOSTART);
			ManifestElement[] allElements = ManifestElement.parseHeader(EclipseAdaptorConstants.ECLIPSE_AUTOSTART, automationHeader);
			//Eclipse-AutoStart not found... look for the Legacy header instead		//TODO This is old code, this can be removed
			if (allElements == null) {
				autoStart = "true".equalsIgnoreCase((String) bundleData.getManifest().get(EclipseAdaptorConstants.LEGACY)); //$NON-NLS-1$
				return;
			}
			// the single value for this element should be true|false
			autoStart = "true".equalsIgnoreCase(allElements[0].getValue()); //$NON-NLS-1$
			// look for any exceptions (the attribute) to the autoActivate setting
			String exceptionsValue = allElements[0].getAttribute(EclipseAdaptorConstants.EXCEPTIONS_ATTRIBUTE);
			if (exceptionsValue != null) {
				StringTokenizer tokenizer = new StringTokenizer(exceptionsValue, ","); //$NON-NLS-1$
				int numberOfTokens = tokenizer.countTokens();
				exceptions = new String[numberOfTokens];
				for (int i = 0; i < numberOfTokens; i++) {
					exceptions[i] = tokenizer.nextToken().trim();
				}
			}
		} catch (BundleException e) {
			// just use the default settings (no auto activation)
			String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CLASSLOADER_CANNOT_GET_HEADERS", bundleData.getLocation()); //$NON-NLS-1$
			EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(EclipseAdaptorConstants.PI_ECLIPSE_OSGI, message, 0, e, null));
		}
	}
	
	public Class findLocalClass(String name) throws ClassNotFoundException {
		if (EclipseAdaptor.MONITOR_CLASSES)	//Suport for performance analysis
			ClassloaderStats.startLoadingClass(getClassloaderId(), name);
		boolean found = true;
		
		try {
			AbstractBundle bundle = (AbstractBundle) hostdata.getBundle();
			// If the bundle is active, just return the class
			if (bundle.getState() == AbstractBundle.ACTIVE)
				return super.findLocalClass(name);
			
			//If the bundle is uninstalled, classes can still be loaded from it
			if (bundle.getState() == AbstractBundle.UNINSTALLED)
				 return super.findLocalClass(name);
			
			//If the bundle is stopping, we don't want to reactive it but we still want to be able to load classes from it.
			if (bundle.getState() == AbstractBundle.STOPPING)
				return super.findLocalClass(name);
			
			// The bundle is not active and does not require activation, just return the class
			if (! shouldActivateFor(name))
				return super.findLocalClass(name);
				
			// The bundle is starting
			if (bundle.getState() == AbstractBundle.STARTING) {
				//If the thread trying to load the class is the one trying to activate the bundle, then return the class 
				if (bundle.testStateChanging(Thread.currentThread()) || bundle.testStateChanging(null))
					return super.findLocalClass(name);
		
				//If it's another thread, we wait and try again. In any case the class is returned. The difference is that an exception can be logged.
				if (! bundle.testStateChanging(Thread.currentThread())) {
					Object lock = bundle.getStateChangeLock();
					long start = System.currentTimeMillis();
					long delay = 5000;
					long timeLeft = delay;
					while (true) {
						if (bundle.testStateChanging(null))
							break;
						
						if (timeLeft <= 0)
							break;
						try {
							synchronized(lock) {
								lock.wait(timeLeft);
							}
						} catch(InterruptedException e) {
							//Ignore and keep waiting
						}
						timeLeft = start + delay - System.currentTimeMillis();
					}
					if (timeLeft <= 0 || bundle.getState() != AbstractBundle.ACTIVE) {
						String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CLASSLOADER_CONCURRENT_STARTUP", new Object[] {Thread.currentThread(), name, bundle.getStateChanging().getName(), bundle.getSymbolicName()==null ? Long.toString(bundle.getBundleId()) : bundle.getSymbolicName()}); //$NON-NLS-1$
						EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(EclipseAdaptorConstants.PI_ECLIPSE_OSGI, message, 0, null, null));
					}
					return super.findLocalClass(name);			
				}
			}
			
			//The bundle must be started.
			try {
				hostdata.getBundle().start();
			} catch (BundleException e) {
				String message = EclipseAdaptorMsg.formatter.getString("ECLIPSE_CLASSLOADER_ACTIVATION", bundle.getSymbolicName(),  Long.toString(bundle.getBundleId())); //$NON-NLS-1$
				EclipseAdaptor.getDefault().getFrameworkLog().log(new FrameworkLogEntry(EclipseAdaptorConstants.PI_ECLIPSE_OSGI, message, 0, e, null));
			} finally {
				return super.findLocalClass(name);
			}
		} catch (ClassNotFoundException e) {
			found = false;
			throw e;
		} finally {
			if (EclipseAdaptor.MONITOR_CLASSES)
				ClassloaderStats.endLoadingClass(getClassloaderId(), name, found);
		}
	}
	/**
	 * Determines if for loading the given class we should activate the bundle. 
	 */
	private boolean shouldActivateFor(String className) {
		//Don't reactivate on shut down
		if (EclipseAdaptor.stopping)	
			return false;
		// no exceptions, it is easy to figure it out
		if (exceptions == null)
			return autoStart;
		// otherwise, we need to check if the package is in the exceptions list
		int dotPosition = className.lastIndexOf('.');
		// the class has no package name... no exceptions apply
		if (dotPosition == -1)
			return autoStart;
		String packageName = className.substring(0, dotPosition);
		// should activate if autoStart and package not in exceptions, or if !autoStart and package in exceptions
		return autoStart ^ exceptionsContained(packageName);
	}
	private boolean exceptionsContained(String packageName) {
		for (int i = 0; i < exceptions.length; i++) {
			if(exceptions[i].equals(packageName))
				return true;
		}
		return false;
	}
	/**
	 * Override defineClass to allow for package defining.
	 */
	protected Class defineClass(String name, byte[] classbytes, int off, int len, ClasspathEntry classpathEntry) throws ClassFormatError {
		// Define the package if it is not the default package.
		int lastIndex = name.lastIndexOf('.');
		if (lastIndex != -1) {
			String packageName = name.substring(0, lastIndex);
			Package pkg = getPackage(packageName);
			if (pkg == null) {
				// get info about the package from the classpath entry's manifest.
				String specTitle = null, specVersion = null, specVendor = null, implTitle = null, implVersion = null, implVendor = null;
				Manifest mf = ((EclipseClasspathEntry) classpathEntry).getManifest();
				if (mf != null) {
					Attributes mainAttributes = mf.getMainAttributes();
					String dirName = packageName.replace('.', '/') + '/';
					Attributes packageAttributes = mf.getAttributes(dirName);
					boolean noEntry = false;
					if (packageAttributes == null) {
						noEntry = true;
						packageAttributes = mainAttributes;
					}
					specTitle = packageAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
					if (specTitle == null && !noEntry)
						specTitle = mainAttributes.getValue(Attributes.Name.SPECIFICATION_TITLE);
					specVersion = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
					if (specVersion == null && !noEntry)
						specVersion = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VERSION);
					specVendor = packageAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
					if (specVendor == null && !noEntry)
						specVendor = mainAttributes.getValue(Attributes.Name.SPECIFICATION_VENDOR);
					implTitle = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
					if (implTitle == null && !noEntry)
						implTitle = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
					implVersion = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
					if (implVersion == null && !noEntry)
						implVersion = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
					implVendor = packageAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
					if (implVendor == null && !noEntry)
						implVendor = mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
				}
				// The package is not defined yet define it before we define the class.
				// TODO still need to seal packages.
				definePackage(packageName, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, null);
			}
		}
		return super.defineClass(name, classbytes, off, len, classpathEntry);
	}
	private String getClassloaderId() {
		return hostdata.getBundle().getSymbolicName();
	}
	public URL getResouce(String name) {
		URL result = super.getResource(name);
		if (EclipseAdaptor.MONITOR_RESOURCE_BUNDLES) {
			if (result != null && name.endsWith(".properties")) { //$NON-NLS-1$
				ClassloaderStats.loadedBundle(getClassloaderId(), new ResourceBundleStats(getClassloaderId(), name, result));
			}
		}
		return result;
	}
	protected void findClassPathEntry(ArrayList result, String entry, AbstractBundleData bundledata, ProtectionDomain domain) {
		String var = hasPrefix(entry);
		if (var == null) {
			super.findClassPathEntry(result, entry, bundledata, domain);
			return;
		}
		if (var.equals("ws")) { //$NON-NLS-1$
			super.findClassPathEntry(result, "ws/" + System.getProperties().getProperty("osgi.ws") + entry.substring(4), bundledata, domain); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			return;
		}
		if (var.equals("os")) { //$NON-NLS-1$
			super.findClassPathEntry(result, "os/" + System.getProperties().getProperty("osgi.os") + entry.substring(4), bundledata, domain); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			return;
		}
		if (var.equals("nl")) { //$NON-NLS-1$
			entry = entry.substring(4);
			for (int i = 0; i < NL_JAR_VARIANTS.length; i++) {
				if (addClassPathEntry(result, "nl/" + NL_JAR_VARIANTS[i] + entry, bundledata, domain)) //$NON-NLS-1$ //$NON-NLS-2$
					return;
			}
			// is we are not in development mode, post some framework errors.
			if (!DevClassPathHelper.inDevelopmentMode()) {
				BundleException be = new BundleException(Msg.formatter.getString("BUNDLE_CLASSPATH_ENTRY_NOT_FOUND_EXCEPTION", entry, hostdata.getLocation())); //$NON-NLS-1$
				bundledata.getAdaptor().getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, bundledata.getBundle(), be);
			}
		}
	}
	private static String[] buildNLJarVariants(String nl) {
		ArrayList result = new ArrayList();
		nl = nl.replace('_', '/');
		while (nl.length() > 0) {
			result.add("nl/" + nl + "/"); //$NON-NLS-1$ //$NON-NLS-2$
			int i = nl.lastIndexOf('/'); //$NON-NLS-1$
			nl = (i < 0) ? "" : nl.substring(0, i); //$NON-NLS-1$
		}
		result.add(""); //$NON-NLS-1$
		return (String[]) result.toArray(new String[result.size()]);
	}
	//return a String representing the string found between the $s
	private String hasPrefix(String libPath) {
		if (libPath.startsWith("$ws$")) //$NON-NLS-1$
			return "ws"; //$NON-NLS-1$
		if (libPath.startsWith("$os$")) //$NON-NLS-1$
			return "os"; //$NON-NLS-1$
		if (libPath.startsWith("$nl$")) //$NON-NLS-1$
			return "nl"; //$NON-NLS-1$
		return null;
	}
	/**
	 * Override to create EclipseClasspathEntry objects.  EclipseClasspathEntry
	 * allows access to the manifest file for the classpath entry.
	 */
	protected ClasspathEntry createClassPathEntry(BundleFile bundlefile, ProtectionDomain domain) {
		return new EclipseClasspathEntry(bundlefile, domain);
	}
	/**
	 * A ClasspathEntry that has a manifest associated with it.
	 */
	protected class EclipseClasspathEntry extends ClasspathEntry {
		Manifest mf;
		boolean initMF = false;
		protected EclipseClasspathEntry(BundleFile bundlefile, ProtectionDomain domain) {
			super(bundlefile, domain);
		}
		public Manifest getManifest() {
			if (initMF)
				return mf;

			BundleEntry mfEntry = getBundleFile().getEntry(org.eclipse.osgi.framework.internal.core.Constants.OSGI_BUNDLE_MANIFEST);
			if (mfEntry != null)
				try {
					InputStream manIn = mfEntry.getInputStream();
					mf = new Manifest(manIn);
					manIn.close();
				} catch (IOException e) {
					// do nothing
				}
			initMF = true;
			return mf;
		}
	}
}