/*******************************************************************************
 * 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.AllPermission;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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;
		}

		@Override
		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;
	static {
		boolean registered;
		try {
			registered = ClassLoader.registerAsParallelCapable();
		} catch (Throwable t) {
			registered = false;
		}
		REGISTERED_AS_PARALLEL = registered;
	}

	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.
	 */
	@Override
	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 | 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.
	 */
	@Override
	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.
	 */
	@Override
	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
	 */
	@Override
	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) {
				signedContent = ((BundleFileWrapperChain) bundlefile).getWrappedType(SignedContent.class);
			}
			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;
		}
	}

	@Override
	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);
	}

	@Override
	public String toString() {
		Bundle b = getBundle();
		StringBuilder result = new StringBuilder(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();
	}
}
