/*******************************************************************************
 * Copyright (c) 2005, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.internal.loader;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.*;
import java.security.cert.Certificate;
import java.util.*;
import org.eclipse.osgi.container.ModuleRevision;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.loader.classpath.ClasspathEntry;
import org.eclipse.osgi.internal.loader.classpath.ClasspathManager;
import org.eclipse.osgi.signedcontent.SignedContent;
import org.eclipse.osgi.signedcontent.SignerInfo;
import org.eclipse.osgi.storage.BundleInfo.Generation;
import org.eclipse.osgi.storage.bundlefile.BundleFile;
import org.eclipse.osgi.storage.bundlefile.BundleFileWrapperChain;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleReference;

public abstract class ModuleClassLoader extends ClassLoader implements BundleReference {
	public static class GenerationProtectionDomain extends ProtectionDomain implements BundleReference {
		private final Generation generation;

		public GenerationProtectionDomain(CodeSource codesource, PermissionCollection permissions, Generation generation) {
			super(codesource, permissions);
			this.generation = generation;
		}

		public Bundle getBundle() {
			return generation.getRevision().getBundle();
		}
	}

	/**
	 * A PermissionCollection for AllPermissions; shared across all ProtectionDomains when security is disabled
	 */
	protected static final PermissionCollection ALLPERMISSIONS;
	protected static final boolean REGISTERED_AS_PARALLEL = ClassLoader.registerAsParallelCapable();

	static {
		AllPermission allPerm = new AllPermission();
		ALLPERMISSIONS = allPerm.newPermissionCollection();
		if (ALLPERMISSIONS != null)
			ALLPERMISSIONS.add(allPerm);
	}

	/**
	 * Holds the result of a defining a class.
	 *
	 */
	public static class DefineClassResult {
		/**
		 * The class object that either got defined or was found as previously loaded.
		 */
		public final Class<?> clazz;
		/**
		 * Set to true if the class object got defined; set to false if the class
		 * did not get defined correctly or the class was found as a previously loaded
		 * class.
		 */
		public final boolean defined;

		public DefineClassResult(Class<?> clazz, boolean defined) {
			this.clazz = clazz;
			this.defined = defined;
		}
	}

	private final Map<String, Thread> classNameLocks = new HashMap<>(5);
	private final Object pkgLock = new Object();

	/**
	 * Constructs a new ModuleClassLoader.
	 * @param parent the parent classloader
	 */
	public ModuleClassLoader(ClassLoader parent) {
		super(parent);
	}

	/**
	 * Returns the generation of the host revision associated with this class loader
	 * @return the generation for this class loader
	 */
	protected abstract Generation getGeneration();

	/**
	 * Returns the Debug object for the Framework instance
	 * @return the Debug object for the Framework instance
	 */
	protected abstract Debug getDebug();

	/**
	 * Returns the classpath manager for this class loader
	 * @return the classpath manager for this class loader
	 */
	public abstract ClasspathManager getClasspathManager();

	/**
	 * Returns the configuration for the Framework instance
	 * @return the configuration for the Framework instance
	 */
	protected abstract EquinoxConfiguration getConfiguration();

	/**
	 * Returns the bundle loader for this class loader
	 * @return the bundle loader for this class loader
	 */
	public abstract BundleLoader getBundleLoader();

	/**
	 * Returns true if this class loader implementation has been
	 * registered with the JVM as a parallel class loader.
	 * This requires Java 7 or later.
	 * @return true if this class loader implementation has been
	 * registered with the JVM as a parallel class loader; otherwise
	 * false is returned.
	 */
	public abstract boolean isRegisteredAsParallel();

	/**
	 * Loads a class for the bundle.  First delegate.findClass(name) is called.
	 * The delegate will query the system class loader, bundle imports, bundle
	 * local classes, bundle hosts and fragments.  The delegate will call 
	 * BundleClassLoader.findLocalClass(name) to find a class local to this 
	 * bundle.  
	 * @param name the name of the class to load.
	 * @param resolve indicates whether to resolve the loaded class or not.
	 * @return The Class object.
	 * @throws ClassNotFoundException if the class is not found.
	 */
	protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
		if (getDebug().DEBUG_LOADER)
			Debug.println("ModuleClassLoader[" + getBundleLoader() + "].loadClass(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
		try {
			// Just ask the delegate.  This could result in findLocalClass(name) being called.
			Class<?> clazz = getBundleLoader().findClass(name);
			// resolve the class if asked to.
			if (resolve)
				resolveClass(clazz);
			return (clazz);
		} catch (Error e) {
			if (getDebug().DEBUG_LOADER) {
				Debug.println("ModuleClassLoader[" + getBundleLoader() + "].loadClass(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				Debug.printStackTrace(e);
			}
			throw e;
		} catch (ClassNotFoundException e) {
			// If the class is not found do not try to look for it locally.
			// The delegate would have already done that for us.
			if (getDebug().DEBUG_LOADER) {
				Debug.println("ModuleClassLoader[" + getBundleLoader() + "].loadClass(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				Debug.printStackTrace(e);
			}
			throw e;
		}
	}

	// preparing for Java 9
	protected Class<?> findClass(String moduleName, String name) {
		try {
			return findLocalClass(name);
		} catch (ClassNotFoundException e) {
			return null;
		}
	}

	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		return findLocalClass(name);
	}

	/**
	 * Gets a resource for the bundle.  First delegate.findResource(name) is 
	 * called. The delegate will query the system class loader, bundle imports,
	 * bundle local resources, bundle hosts and fragments.  The delegate will 
	 * call BundleClassLoader.findLocalResource(name) to find a resource local 
	 * to this bundle.  
	 * @param name The resource path to get.
	 * @return The URL of the resource or null if it does not exist.
	 */
	public URL getResource(String name) {
		if (getDebug().DEBUG_LOADER) {
			Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResource(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}

		URL url = getBundleLoader().findResource(name);
		if (url != null)
			return (url);

		if (getDebug().DEBUG_LOADER) {
			Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResource(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}

		return (null);
	}

	// preparing for Java 9
	protected URL findResource(String moduleName, String name) {
		return findLocalResource(name);
	}

	@Override
	protected URL findResource(String name) {
		return findLocalResource(name);
	}

	/**
	 * Gets resources for the bundle.  First delegate.findResources(name) is
	 * called. The delegate will query the system class loader, bundle imports,
	 * bundle local resources, bundle hosts and fragments.  The delegate will
	 * call BundleClassLoader.findLocalResources(name) to find a resource local
	 * to this bundle.
	 * @param name The resource path to get.
	 * @return The Enumeration of the resource URLs.
	 */
	public Enumeration<URL> getResources(String name) throws IOException {
		if (getDebug().DEBUG_LOADER) {
			Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResources(" + name + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		Enumeration<URL> result = getBundleLoader().findResources(name);
		if (getDebug().DEBUG_LOADER) {
			if (result == null || !result.hasMoreElements()) {
				Debug.println("ModuleClassLoader[" + getBundleLoader() + "].getResources(" + name + ") failed."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
		}
		return result;
	}

	@Override
	protected Enumeration<URL> findResources(String name) throws IOException {
		return findLocalResources(name);
	}

	/**
	 * Finds a library for this bundle.  Simply calls 
	 * manager.findLibrary(libname) to find the library.
	 * @param libname The library to find.
	 * @return The absolution path to the library or null if not found
	 */
	protected String findLibrary(String libname) {
		// let the manager find the library for us
		return getClasspathManager().findLibrary(libname);
	}

	public ClasspathEntry createClassPathEntry(BundleFile bundlefile, Generation entryGeneration) {
		return new ClasspathEntry(bundlefile, createProtectionDomain(bundlefile, entryGeneration), entryGeneration);
	}

	public DefineClassResult defineClass(String name, byte[] classbytes, ClasspathEntry classpathEntry) {
		// Note that we must check findLoadedClass again here since no locks are held between
		// calling findLoadedClass the first time and defineClass.
		// This is to allow weavers to get called while holding no locks.
		// See ClasspathManager.findLocalClass(String)
		boolean defined = false;
		Class<?> result = null;
		if (isRegisteredAsParallel()) {
			// lock by class name in this case
			boolean initialLock = lockClassName(name);
			try {
				result = findLoadedClass(name);
				if (result == null) {
					result = defineClass(name, classbytes, 0, classbytes.length, classpathEntry.getDomain());
					defined = true;
				}
			} finally {
				if (initialLock) {
					unlockClassName(name);
				}
			}
		} else {
			// lock by class loader instance in this case
			synchronized (this) {
				result = findLoadedClass(name);
				if (result == null) {
					result = defineClass(name, classbytes, 0, classbytes.length, classpathEntry.getDomain());
					defined = true;
				}
			}
		}
		return new DefineClassResult(result, defined);
	}

	public Class<?> publicFindLoaded(String classname) {
		if (isRegisteredAsParallel()) {
			return findLoadedClass(classname);
		}
		synchronized (this) {
			return findLoadedClass(classname);
		}
	}

	public Package publicGetPackage(String pkgname) {
		synchronized (pkgLock) {
			return getPackage(pkgname);
		}
	}

	public Package publicDefinePackage(String name, String specTitle, String specVersion, String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase) {
		synchronized (pkgLock) {
			Package pkg = getPackage(name);
			return pkg != null ? pkg : definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
		}
	}

	public URL findLocalResource(String resource) {
		return getClasspathManager().findLocalResource(resource);
	}

	public Enumeration<URL> findLocalResources(String resource) {
		return getClasspathManager().findLocalResources(resource);
	}

	public Class<?> findLocalClass(String classname) throws ClassNotFoundException {
		return getClasspathManager().findLocalClass(classname);
	}

	/**
	 * Creates a ProtectionDomain which uses specified BundleFile and the permissions of the baseDomain
	 * @param bundlefile The source bundlefile the domain is for.
	 * @param domainGeneration the source generation for the domain
	 * @return a ProtectionDomain which uses specified BundleFile and the permissions of the baseDomain 
	 */
	@SuppressWarnings("deprecation")
	protected ProtectionDomain createProtectionDomain(BundleFile bundlefile, Generation domainGeneration) {
		// create a protection domain which knows about the codesource for this classpath entry (bug 89904)
		ProtectionDomain baseDomain = domainGeneration.getDomain();
		try {
			// use the permissions supplied by the domain passed in from the framework
			PermissionCollection permissions;
			if (baseDomain != null) {
				permissions = baseDomain.getPermissions();
			} else {
				// no domain specified.  Better use a collection that has all permissions
				// this is done just incase someone sets the security manager later
				permissions = ALLPERMISSIONS;
			}
			Certificate[] certs = null;
			SignedContent signedContent = null;
			if (bundlefile instanceof BundleFileWrapperChain) {
				BundleFileWrapperChain wrapper = (BundleFileWrapperChain) bundlefile;
				while (wrapper != null && (!(wrapper.getWrapped() instanceof SignedContent)))
					wrapper = wrapper.getNext();
				signedContent = wrapper == null ? null : (SignedContent) wrapper.getWrapped();
			}
			if (getConfiguration().CLASS_CERTIFICATE && signedContent != null && signedContent.isSigned()) {
				SignerInfo[] signers = signedContent.getSignerInfos();
				if (signers.length > 0)
					certs = signers[0].getCertificateChain();
			}
			File file = bundlefile.getBaseFile();
			// Bug 477787: file will be null when the osgi.framework configuration property contains an invalid value.
			return new GenerationProtectionDomain(file == null ? null : new CodeSource(file.toURL(), certs), permissions, getGeneration());
			//return new ProtectionDomain(new CodeSource(bundlefile.getBaseFile().toURL(), certs), permissions);
		} catch (MalformedURLException e) {
			// Failed to create our own domain; just return the baseDomain
			return baseDomain;
		}
	}

	public Bundle getBundle() {
		return getGeneration().getRevision().getBundle();
	}

	public List<URL> findEntries(String path, String filePattern, int options) {
		return getClasspathManager().findEntries(path, filePattern, options);
	}

	public Collection<String> listResources(String path, String filePattern, int options) {
		return getBundleLoader().listResources(path, filePattern, options);
	}

	public Collection<String> listLocalResources(String path, String filePattern, int options) {
		return getClasspathManager().listLocalResources(path, filePattern, options);
	}

	public String toString() {
		Bundle b = getBundle();
		StringBuffer result = new StringBuffer(super.toString());
		if (b == null)
			return result.toString();
		return result.append('[').append(b.getSymbolicName()).append(':').append(b.getVersion()).append("(id=").append(b.getBundleId()).append(")]").toString(); //$NON-NLS-1$//$NON-NLS-2$
	}

	public void loadFragments(Collection<ModuleRevision> fragments) {
		getClasspathManager().loadFragments(fragments);
	}

	private boolean lockClassName(String classname) {
		synchronized (classNameLocks) {
			Object lockingThread = classNameLocks.get(classname);
			Thread current = Thread.currentThread();
			if (lockingThread == current)
				return false;
			boolean previousInterruption = Thread.interrupted();
			try {
				while (true) {
					if (lockingThread == null) {
						classNameLocks.put(classname, current);
						return true;
					}

					classNameLocks.wait();
					lockingThread = classNameLocks.get(classname);
				}
			} catch (InterruptedException e) {
				previousInterruption = true;
				// must not throw LinkageError or ClassNotFoundException here because that will cause all threads
				// to fail to load the class (see bug 490902)
				throw new Error("Interrupted while waiting for classname lock: " + classname, e); //$NON-NLS-1$
			} finally {
				if (previousInterruption) {
					current.interrupt();
				}
			}
		}
	}

	private void unlockClassName(String classname) {
		synchronized (classNameLocks) {
			classNameLocks.remove(classname);
			classNameLocks.notifyAll();
		}
	}

	public void close() {
		getClasspathManager().close();
	}
}
