/*******************************************************************************
 * Copyright (c) 2000, 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
 *     Ericsson AB, Hamdan Msheik - Bug 389564
 *     Ericsson AB, Julian Enoch - Bug 470390
 *******************************************************************************/
package org.eclipse.ant.internal.launching.launchConfigurations;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.ant.core.AntCorePlugin;
import org.eclipse.ant.core.AntCorePreferences;
import org.eclipse.ant.core.IAntClasspathEntry;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.launching.AntLaunching;
import org.eclipse.ant.internal.launching.AntLaunchingUtil;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.osgi.framework.Bundle;
import org.osgi.framework.namespace.HostNamespace;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * A classpath entry that contains a contributed classpath entries via the <code>extraClasspathEntries</code> extension point.
 * 
 * @since 3.0
 */
@SuppressWarnings("restriction")
public class ContributedClasspathEntriesEntry extends AbstractRuntimeClasspathEntry {

	public static final String TYPE_ID = "org.eclipse.ant.ui.classpathentry.extraClasspathEntries"; //$NON-NLS-1$

	public static List<IRuntimeClasspathEntry> fgSWTEntries = null;

	/**
	 * Default contructor required to instantiate persisted extensions.
	 */
	public ContributedClasspathEntriesEntry() {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.internal.launching.AbstractRuntimeClasspathEntry#buildMemento(org.w3c.dom.Document, org.w3c.dom.Element)
	 */
	@Override
	protected void buildMemento(Document document, Element memento) throws CoreException {
		// do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.internal.launching.IRuntimeClasspathEntry2#initializeFrom(org.w3c.dom.Element)
	 */
	@Override
	public void initializeFrom(Element memento) throws CoreException {
		// do nothing
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getTypeId()
	 */
	@Override
	public String getTypeId() {
		return TYPE_ID;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getRuntimeClasspathEntries(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public IRuntimeClasspathEntry[] getRuntimeClasspathEntries(ILaunchConfiguration configuration) throws CoreException {
		boolean separateVM = AntLaunchingUtil.isSeparateJREAntBuild(configuration);
		boolean setInputHandler = configuration.getAttribute(AntLaunching.SET_INPUTHANDLER, true);
		AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
		IAntClasspathEntry[] antClasspathEntries = prefs.getContributedClasspathEntries();
		IAntClasspathEntry[] userEntries = prefs.getAdditionalClasspathEntries();
		List<IRuntimeClasspathEntry> rtes = new ArrayList<>(antClasspathEntries.length + userEntries.length);
		IAntClasspathEntry entry;
		for (int i = 0; i < antClasspathEntries.length; i++) {
			entry = antClasspathEntries[i];
			if (!separateVM || (separateVM && !entry.isEclipseRuntimeRequired())) {
				rtes.add(JavaRuntime.newStringVariableClasspathEntry(entry.getLabel()));
			}
		}
		boolean haveToolsEntry = false;
		String path;
		for (int i = 0; i < userEntries.length; i++) {
			entry = userEntries[i];
			path = entry.getLabel();
			IPath toolsPath = new Path(path);
			if (toolsPath.lastSegment().equals("tools.jar")) { //$NON-NLS-1$
				haveToolsEntry = true;
				// replace with dynamically resolved tools.jar based on
				// the JRE being used
				addToolsJar(configuration, rtes, path);
			} else {
				rtes.add(JavaRuntime.newStringVariableClasspathEntry(path));
			}
		}
		if (!haveToolsEntry) {
			addToolsJar(configuration, rtes, null);
		}

		if (setInputHandler && separateVM) {
			addSWTJars(rtes);
		}

		return rtes.toArray(new IRuntimeClasspathEntry[rtes.size()]);
	}

	private void addToolsJar(ILaunchConfiguration configuration, List<IRuntimeClasspathEntry> rtes, String path) {
		IRuntimeClasspathEntry tools = getToolsJar(configuration);
		if (tools == null) {
			if (path != null) {
				// use the global entry
				rtes.add(JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(path)));
			} else {
				// use the default vm install to try to find a tools.jar
				IVMInstall install = JavaRuntime.getDefaultVMInstall();
				if (install != null) {
					IAntClasspathEntry entry = AntCorePlugin.getPlugin().getPreferences().getToolsJarEntry(new Path(install.getInstallLocation().getAbsolutePath()));
					if (entry != null) {
						String pathString = null;
						try {
							pathString = URIUtil.toURL(URIUtil.toURI(entry.getEntryURL())).getPath();
							rtes.add(JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(pathString)));
						}
						catch (MalformedURLException e) {
							AntLaunching.log(e);

						}
						catch (URISyntaxException e) {
							AntLaunching.log(e);
						}
					}
				}
			}
		} else {
			rtes.add(tools);
		}
	}

	private void addSWTJars(List<IRuntimeClasspathEntry> rtes) {
		if (fgSWTEntries == null) {
			fgSWTEntries = new ArrayList<>();
			Bundle bundle = Platform.getBundle("org.eclipse.swt"); //$NON-NLS-1$
			BundleWiring wiring = bundle.adapt(BundleWiring.class);
			List<BundleWire> fragmentWires = wiring == null ? Collections.<BundleWire> emptyList()
					: wiring.getProvidedWires(HostNamespace.HOST_NAMESPACE);
			for (BundleWire fragmentWire : fragmentWires) {
				Bundle fragmentBundle = fragmentWire.getRequirer().getBundle();
				URL bundleURL;
				try {
					bundleURL = FileLocator.resolve(fragmentBundle.getEntry("/")); //$NON-NLS-1$
				}
				catch (IOException e) {
					AntLaunching.log(e);
					continue;
				}
				String urlFileName = bundleURL.getFile();
				if (urlFileName.startsWith(IAntCoreConstants.FILE_PROTOCOL)) {
					try {
						try {
							URI uri = URIUtil.toURI(new URL(urlFileName));
							// fix bug 470390 using toFile() instead of toURL()
							urlFileName = URIUtil.toFile(uri).getAbsolutePath();
						}
						catch (URISyntaxException e) {
							AntLaunching.log(e);
						}
						if (urlFileName.endsWith("!/") || urlFileName.endsWith("!\\")) { //$NON-NLS-1$ //$NON-NLS-2$
							urlFileName = urlFileName.substring(0, urlFileName.length() - 2);
						}
						if (urlFileName.endsWith("!")) { //$NON-NLS-1$
							urlFileName = urlFileName.substring(0, urlFileName.length() - 1);
						}
					}
					catch (MalformedURLException e) {
						AntLaunching.log(e);
						continue;
					}
				}
				IPath fragmentPath = new Path(urlFileName);
				if (fragmentPath.getFileExtension() != null) { // JAR file
					fgSWTEntries.add(JavaRuntime.newArchiveRuntimeClasspathEntry(fragmentPath));
				} else { // folder
					File bundleFolder = fragmentPath.toFile();
					if (!bundleFolder.isDirectory()) {
						continue;
					}
					String[] names = bundleFolder.list(new FilenameFilter() {
						@Override
						public boolean accept(File dir, String name) {
							return name.endsWith(".jar"); //$NON-NLS-1$
						}
					});
					for (int j = 0; j < names.length; j++) {
						String jarName = names[j];
						fgSWTEntries.add(JavaRuntime.newArchiveRuntimeClasspathEntry(fragmentPath.append(jarName)));
					}
				}
			}
		}
		rtes.addAll(fgSWTEntries);
	}

	/**
	 * Returns the tools.jar to use for this launch configuration, or <code>null</code> if none.
	 * 
	 * @param configuration
	 *            configuration to resolve a tools.jar for
	 * @return associated tools.jar archive, or <code>null</code>
	 */
	private IRuntimeClasspathEntry getToolsJar(ILaunchConfiguration configuration) {
		try {
			IVMInstall install = JavaRuntime.computeVMInstall(configuration);
			if (install != null) {
				IAntClasspathEntry entry = AntCorePlugin.getPlugin().getPreferences().getToolsJarEntry(new Path(install.getInstallLocation().getAbsolutePath()));
				if (entry != null) {
					return JavaRuntime.newArchiveRuntimeClasspathEntry(new Path(entry.getEntryURL().getPath()));
				}
			}
		}
		catch (CoreException ce) {
			// likely dealing with a non-Java project
		}

		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#getName()
	 */
	@Override
	public String getName() {
		return AntLaunchConfigurationMessages.ContributedClasspathEntriesEntry_1;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry#getType()
	 */
	@Override
	public int getType() {
		return IRuntimeClasspathEntry.OTHER;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.launching.IRuntimeClasspathEntry2#isComposite()
	 */
	@Override
	public boolean isComposite() {
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		return obj instanceof ContributedClasspathEntriesEntry;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return getClass().hashCode();
	}
}
