/*******************************************************************************
 * Copyright (c) 2008, 2018 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
 *******************************************************************************/

/**
 * The java.net.URLClassLoader class allows one to load resources from arbitrary URLs and in particular is optimized to handle
 * "jar" URLs. Unfortunately for jar files this optimization ends up holding the file open which ultimately prevents the file from
 * being deleted or update until the VM is shutdown.
 *
 * The CloseableURLClassLoader is meant to replace the URLClassLoader and provides an additional method to allow one to "close" any
 * resources left open. In the current version the CloseableURLClassLoader will only ensure the closing of jar file resources. The
 * jar handling behavior in this class will also provides a construct to allow one to turn off jar file verification in performance
 * sensitive situations where the verification us not necessary.
 *
 * also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=190279
 */

package org.eclipse.equinox.servletbridge;

import java.io.*;
import java.lang.reflect.Method;
import java.net.*;
import java.security.*;
import java.util.*;
import java.util.jar.*;
import java.util.jar.Attributes.Name;

public class CloseableURLClassLoader extends URLClassLoader {
	private static final boolean CLOSEABLE_REGISTERED_AS_PARALLEL;
	static {
		boolean registeredAsParallel;
		try {
			Method parallelCapableMetod = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable", (Class[]) null); //$NON-NLS-1$
			parallelCapableMetod.setAccessible(true);
			registeredAsParallel = ((Boolean) parallelCapableMetod.invoke(null, (Object[]) null)).booleanValue();
		} catch (Throwable e) {
			// must do everything to avoid failing in clinit
			registeredAsParallel = true;
		}
		CLOSEABLE_REGISTERED_AS_PARALLEL = registeredAsParallel;
	}
	static final String DOT_CLASS = ".class"; //$NON-NLS-1$
	static final String BANG_SLASH = "!/"; //$NON-NLS-1$
	static final String JAR = "jar"; //$NON-NLS-1$
	private static final String UNC_PREFIX = "//"; //$NON-NLS-1$
	private static final String SCHEME_FILE = "file"; //$NON-NLS-1$

	// @GuardedBy("loaders")
	final ArrayList<CloseableJarFileLoader> loaders = new ArrayList<>(); // package private to avoid synthetic access.
	// @GuardedBy("loaders")
	private final ArrayList<URL> loaderURLs = new ArrayList<>(); // note: protected by loaders
	// @GuardedBy("loaders")
	boolean closed = false; // note: protected by loaders, package private to avoid synthetic access.

	private final AccessControlContext context;
	private final boolean verifyJars;
	private final boolean registeredAsParallel;

	private static class CloseableJarURLConnection extends JarURLConnection {
		private final JarFile jarFile;
		// @GuardedBy("this")
		private JarEntry entry;

		public CloseableJarURLConnection(URL url, JarFile jarFile) throws MalformedURLException {
			super(url);
			this.jarFile = jarFile;
		}

		@Override
		public void connect() throws IOException {
			internalGetEntry();
		}

		private synchronized JarEntry internalGetEntry() throws IOException {
			if (entry != null)
				return entry;
			entry = jarFile.getJarEntry(getEntryName());
			if (entry == null)
				throw new FileNotFoundException(getEntryName());
			return entry;
		}

		@Override
		public InputStream getInputStream() throws IOException {
			return jarFile.getInputStream(internalGetEntry());
		}

		/**
		 * @throws IOException
		 * Documented to avoid warning
		 */
		@Override
		public JarFile getJarFile() throws IOException {
			return jarFile;
		}

		@Override
		public JarEntry getJarEntry() throws IOException {
			return internalGetEntry();
		}
	}

	private static class CloseableJarURLStreamHandler extends URLStreamHandler {
		private final JarFile jarFile;

		public CloseableJarURLStreamHandler(JarFile jarFile) {
			this.jarFile = jarFile;
		}

		@Override
		protected URLConnection openConnection(URL u) throws IOException {
			return new CloseableJarURLConnection(u, jarFile);
		}

		@Override
		protected void parseURL(URL u, String spec, int start, int limit) {
			setURL(u, JAR, null, 0, null, null, spec.substring(start, limit), null, null);
		}
	}

	private static class CloseableJarFileLoader {
		private final JarFile jarFile;
		private final Manifest manifest;
		private final CloseableJarURLStreamHandler jarURLStreamHandler;
		private final String jarFileURLPrefixString;

		public CloseableJarFileLoader(File file, boolean verify) throws IOException {
			this.jarFile = new JarFile(file, verify);
			this.manifest = jarFile.getManifest();
			this.jarURLStreamHandler = new CloseableJarURLStreamHandler(jarFile);
			this.jarFileURLPrefixString = file.toURL().toString() + BANG_SLASH;
		}

		public URL getURL(String name) {
			if (jarFile.getEntry(name) != null)
				try {
					return new URL(JAR, null, -1, jarFileURLPrefixString + name, jarURLStreamHandler);
				} catch (MalformedURLException e) {
					// ignore
				}
			return null;
		}

		public Manifest getManifest() {
			return manifest;
		}

		public void close() {
			try {
				jarFile.close();
			} catch (IOException e) {
				// ignore
			}
		}
	}

	/**
	 * @param urls the array of URLs to use for loading resources
	 * @see URLClassLoader
	 */
	public CloseableURLClassLoader(URL[] urls) {
		this(urls, ClassLoader.getSystemClassLoader(), true);
	}

	/**
	 * @param urls the URLs from which to load classes and resources
	 * @param parent the parent class loader used for delegation
	 * @see URLClassLoader
	 */
	public CloseableURLClassLoader(URL[] urls, ClassLoader parent) {
		this(excludeFileJarURLS(urls), parent, true);
	}

	/**
	 * @param urls the URLs from which to load classes and resources
	 * @param parent the parent class loader used for delegation
	 * @param verifyJars flag to determine if jar file verification should be performed
	 * @see URLClassLoader
	 */
	public CloseableURLClassLoader(URL[] urls, ClassLoader parent, boolean verifyJars) {
		super(excludeFileJarURLS(urls), parent);
		this.registeredAsParallel = CLOSEABLE_REGISTERED_AS_PARALLEL && this.getClass() == CloseableURLClassLoader.class;
		this.context = AccessController.getContext();
		this.verifyJars = verifyJars;
		for (int i = 0; i < urls.length; i++) {
			if (isFileJarURL(urls[i])) {
				loaderURLs.add(urls[i]);
				safeAddLoader(urls[i]);
			}
		}
	}

	// @GuardedBy("loaders")
	private boolean safeAddLoader(URL url) {
		//assume all illegal characters have been properly encoded, so use URI class to unencode
		try {
			File file = new File(toURI(url));
			if (file.exists()) {
				try {
					loaders.add(new CloseableJarFileLoader(file, verifyJars));
					return true;
				} catch (IOException e) {
					// ignore
				}
			}
		} catch (URISyntaxException e1) {
			// ignore
		}

		return false;
	}

	private static URI toURI(URL url) throws URISyntaxException {
		if (!SCHEME_FILE.equals(url.getProtocol())) {
			throw new IllegalArgumentException("bad prototcol: " + url.getProtocol()); //$NON-NLS-1$
		}
		//URL behaves differently across platforms so for file: URLs we parse from string form
		String pathString = url.toExternalForm().substring(5);
		//ensure there is a leading slash to handle common malformed URLs such as file:c:/tmp
		if (pathString.indexOf('/') != 0)
			pathString = '/' + pathString;
		else if (pathString.startsWith(UNC_PREFIX) && !pathString.startsWith(UNC_PREFIX, 2)) {
			//URL encodes UNC path with two slashes, but URI uses four (see bug 207103)
			pathString = ensureUNCPath(pathString);
		}
		return new URI(SCHEME_FILE, null, pathString, null);
	}

	/**
	 * Ensures the given path string starts with exactly four leading slashes.
	 */
	private static String ensureUNCPath(String path) {
		int len = path.length();
		StringBuffer result = new StringBuffer(len);
		for (int i = 0; i < 4; i++) {
			//	if we have hit the first non-slash character, add another leading slash
			if (i >= len || result.length() > 0 || path.charAt(i) != '/')
				result.append('/');
		}
		result.append(path);
		return result.toString();
	}

	private static URL[] excludeFileJarURLS(URL[] urls) {
		ArrayList<URL> urlList = new ArrayList<>();
		for (int i = 0; i < urls.length; i++) {
			if (!isFileJarURL(urls[i]))
				urlList.add(urls[i]);
		}
		return urlList.toArray(new URL[urlList.size()]);
	}

	private static boolean isFileJarURL(URL url) {
		if (!url.getProtocol().equals("file")) //$NON-NLS-1$
			return false;

		String path = url.getPath();
		if (path != null && path.endsWith("/")) //$NON-NLS-1$
			return false;

		return true;
	}

	@Override
	protected Class<?> findClass(final String name) throws ClassNotFoundException {
		try {
			Class<?> clazz = AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
				@Override
				public Class<?> run() throws ClassNotFoundException {
					String resourcePath = name.replace('.', '/') + DOT_CLASS;
					CloseableJarFileLoader loader = null;
					URL resourceURL = null;
					synchronized (loaders) {
						if (closed)
							return null;
						for (Iterator<CloseableJarFileLoader> iterator = loaders.iterator(); iterator.hasNext();) {
							loader = iterator.next();
							resourceURL = loader.getURL(resourcePath);
							if (resourceURL != null)
								break;
						}
					}
					if (resourceURL != null) {
						try {
							return defineClass(name, resourceURL, loader.getManifest());
						} catch (IOException e) {
							throw new ClassNotFoundException(name, e);
						}
					}
					return null;
				}
			}, context);
			if (clazz != null)
				return clazz;
		} catch (PrivilegedActionException e) {
			throw (ClassNotFoundException) e.getException();
		}
		return super.findClass(name);
	}

	// package private to avoid synthetic access.
	Class<?> defineClass(String name, URL resourceURL, Manifest manifest) throws IOException {
		JarURLConnection connection = (JarURLConnection) resourceURL.openConnection();
		int lastDot = name.lastIndexOf('.');
		if (lastDot != -1) {
			String packageName = name.substring(0, lastDot);
			synchronized (pkgLock) {
				Package pkg = getPackage(packageName);
				if (pkg != null) {
					checkForSealedPackage(pkg, packageName, manifest, connection.getJarFileURL());
				} else {
					definePackage(packageName, manifest, connection.getJarFileURL());
				}
			}

		}
		JarEntry entry = connection.getJarEntry();
		byte[] bytes = new byte[(int) entry.getSize()];
		DataInputStream is = null;
		try {
			is = new DataInputStream(connection.getInputStream());
			is.readFully(bytes, 0, bytes.length);
			CodeSource cs = new CodeSource(connection.getJarFileURL(), entry.getCertificates());
			if (isRegisteredAsParallel()) {
				boolean initialLock = lockClassName(name);
				try {
					Class<?> clazz = findLoadedClass(name);
					if (clazz != null) {
						return clazz;
					}
					return defineClass(name, bytes, 0, bytes.length, cs);
				} finally {
					if (initialLock) {
						unlockClassName(name);
					}
				}
			}
			return defineClass(name, bytes, 0, bytes.length, cs);
		} finally {
			if (is != null)
				try {
					is.close();
				} catch (IOException e) {
					// ignore
				}
		}
	}

	private void checkForSealedPackage(Package pkg, String packageName, Manifest manifest, URL jarFileURL) {
		if (pkg.isSealed()) {
			// previously sealed case
			if (!pkg.isSealed(jarFileURL)) {
				// this URL does not seal; ERROR
				throw new SecurityException("The package '" + packageName + "' was previously loaded and is already sealed."); //$NON-NLS-1$ //$NON-NLS-2$
			}
		} else {
			// previously unsealed case
			String entryPath = packageName.replace('.', '/') + "/"; //$NON-NLS-1$
			Attributes entryAttributes = manifest.getAttributes(entryPath);
			String sealed = null;
			if (entryAttributes != null)
				sealed = entryAttributes.getValue(Name.SEALED);

			if (sealed == null) {
				Attributes mainAttributes = manifest.getMainAttributes();
				if (mainAttributes != null)
					sealed = mainAttributes.getValue(Name.SEALED);
			}
			if (Boolean.valueOf(sealed).booleanValue()) {
				// this manifest attempts to seal when package defined previously unsealed; ERROR
				throw new SecurityException("The package '" + packageName + "' was previously loaded unsealed. Cannot seal package."); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	@Override
	public URL findResource(final String name) {
		URL url = AccessController.doPrivileged(new PrivilegedAction<URL>() {
			@Override
			public URL run() {
				synchronized (loaders) {
					if (closed)
						return null;
					for (Iterator<CloseableJarFileLoader> iterator = loaders.iterator(); iterator.hasNext();) {
						CloseableJarFileLoader loader = iterator.next();
						URL resourceURL = loader.getURL(name);
						if (resourceURL != null)
							return resourceURL;
					}
				}
				return null;
			}
		}, context);
		if (url != null)
			return url;
		return super.findResource(name);
	}

	@Override
	public Enumeration<URL> findResources(final String name) throws IOException {
		final List<URL> resources = new ArrayList<>();
		AccessController.doPrivileged(new PrivilegedAction<Object>() {
			@Override
			public Object run() {
				synchronized (loaders) {
					if (closed)
						return null;
					for (Iterator<CloseableJarFileLoader> iterator = loaders.iterator(); iterator.hasNext();) {
						CloseableJarFileLoader loader = iterator.next();
						URL resourceURL = loader.getURL(name);
						if (resourceURL != null)
							resources.add(resourceURL);
					}
				}
				return null;
			}
		}, context);
		Enumeration<URL> e = super.findResources(name);
		while (e.hasMoreElements())
			resources.add(e.nextElement());

		return Collections.enumeration(resources);
	}

	/**
	 * The "close" method is called when the class loader is no longer needed and we should close any open resources.
	 * In particular this method will close the jar files associated with this class loader.
	 */
	@Override
	public void close() {
		synchronized (loaders) {
			if (closed)
				return;
			for (Iterator<CloseableJarFileLoader> iterator = loaders.iterator(); iterator.hasNext();) {
				CloseableJarFileLoader loader = iterator.next();
				loader.close();
			}
			closed = true;
		}
	}

	@Override
	protected void addURL(URL url) {
		synchronized (loaders) {
			if (isFileJarURL(url)) {
				if (closed)
					throw new IllegalStateException("Cannot add url. CloseableURLClassLoader is closed."); //$NON-NLS-1$
				loaderURLs.add(url);
				if (safeAddLoader(url))
					return;
			}
		}
		super.addURL(url);
	}

	@Override
	public URL[] getURLs() {
		List<URL> result = new ArrayList<>();
		synchronized (loaders) {
			result.addAll(loaderURLs);
		}
		result.addAll(Arrays.asList(super.getURLs()));
		return result.toArray(new URL[result.size()]);
	}

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

	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) {
				current.interrupt();
				throw (LinkageError) new LinkageError(classname).initCause(e);
			} finally {
				if (previousInterruption) {
					current.interrupt();
				}
			}
		}
	}

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

	protected boolean isRegisteredAsParallel() {
		return registeredAsParallel;
	}
}
