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

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.osgi.service.datalocation.Location;
import org.eclipse.pde.core.plugin.TargetPlatform;
import org.eclipse.update.configurator.ConfiguratorUtils;
import org.eclipse.update.configurator.IPlatformConfiguration;
import org.eclipse.update.configurator.IPlatformConfiguration.ISiteEntry;

@SuppressWarnings("deprecation")
// PDE still supports searching the platform.xml for plug-in/feature listings
public class PluginPathFinder {

	private static final String URL_PROPERTY = "org.eclipse.update.resolution_url"; //$NON-NLS-1$
	private static final String EMPTY_STRING = ""; //$NON-NLS-1$

	/**
	 *
	 * @param platformHome
	 * @param linkFile
	 * @param features false for plugins, true for features
	 * @return path of plugins or features directory of an extension site
	 */
	private static String getSitePath(String platformHome, File linkFile, boolean features) {
		String prefix = new Path(platformHome).removeLastSegments(1).toString();
		Properties properties = new Properties();
		try {
			FileInputStream fis = new FileInputStream(linkFile);
			properties.load(fis);
			fis.close();
			String path = properties.getProperty("path"); //$NON-NLS-1$
			if (path != null) {
				if (!new Path(path).isAbsolute())
					path = prefix + IPath.SEPARATOR + path;
				path += IPath.SEPARATOR + "eclipse" + IPath.SEPARATOR; //$NON-NLS-1$
				if (features)
					path += "features"; //$NON-NLS-1$
				else
					path += "plugins"; //$NON-NLS-1$
				if (new File(path).exists()) {
					return path;
				}
			}
		} catch (IOException e) {
		}
		return null;
	}

	/**
	 *
	 * @param platformHome
	 * @param features false for plugin sites, true for feature sites
	 * @return array of ".../plugins" or ".../features" Files
	 */
	private static File[] getSites(String platformHome, boolean features) {
		HashSet<File> sites = new HashSet<>();
		File file = new File(platformHome, features ? "features" : "plugins"); //$NON-NLS-1$ //$NON-NLS-2$
		if (!features && !file.exists())
			file = new File(platformHome);
		if (file.exists())
			sites.add(file);

		File[] linkFiles = new File(platformHome + IPath.SEPARATOR + "links").listFiles(); //$NON-NLS-1$
		if (linkFiles != null) {
			for (File linkFile : linkFiles) {
				String path = getSitePath(platformHome, linkFile, features);
				if (path != null) {
					sites.add(new File(path));
				}
			}
		}

		// If there is no features/plugins folder and no linked files, try the home location
		if (sites.isEmpty()) {
			file = new File(platformHome);
			if (file.exists()) {
				sites.add(file);
			}
		}

		return sites.toArray(new File[sites.size()]);
	}

	/**
	 * Attempts to find all plugin paths if the target platform was at the given string location.
	 * <p>
	 * Should not be called in PDE. It should only be used to confirm test results match the
	 * old way of doing things (before ITargetPlatformService).
	 * </p>
	 *
	 * @param platformHome the target platform location
	 * @param installedOnly whether to check for a bundles.info or another configuration file to
	 * 		determine what bundles are installed rather than what bundles simply exist in the plugins folder
	 * @return list of URL plug-in locations
	 */
	public static URL[] getPluginPaths(String platformHome, boolean installedOnly) {
		// If we don't care about installed bundles, simply scan the location
		if (!installedOnly)
			return scanLocations(getSites(platformHome, false));

		// See if we can find a bundles.info to get installed bundles from
		URL[] urls = null;
		if (new Path(platformHome).equals(new Path(TargetPlatform.getDefaultLocation()))) {
			// Pointing at default install, so use the actual configuration area
			Location configArea = Platform.getConfigurationLocation();

			if (configArea != null) {
				urls = P2Utils.readBundlesTxt(platformHome, configArea.getURL());

				// try the shared location (parent)
				if (urls == null && configArea.getParentLocation() != null) {
					urls = P2Utils.readBundlesTxt(platformHome, configArea.getParentLocation().getURL());
				}
			}

		} else {
			// Pointing at a folder, so try to guess the configuration area
			File configurationArea = new File(platformHome, "configuration"); //$NON-NLS-1$
			if (configurationArea.exists()) {
				try {
					urls = P2Utils.readBundlesTxt(platformHome, configurationArea.toURL());
				} catch (MalformedURLException e) {
					PDECore.log(e);
				}
			}
		}
		if (urls != null) {
			return urls;
		}

		if (new Path(platformHome).equals(new Path(TargetPlatform.getDefaultLocation())) && !isDevLaunchMode())
			return ConfiguratorUtils.getCurrentPlatformConfiguration().getPluginPath();

		return getPlatformXMLPaths(platformHome, false);
	}

	public static URL[] getFeaturePaths(String platformHome) {
		return getPlatformXMLPaths(platformHome, true);
	}

	/**
	 * Returns a list of file URLs for plug-ins or features found in a platform.xml file or in the default
	 * directory ("plugins"/"features") if no platform.xml is available.
	 *
	 * @param platformHome base location for the installation, used to search for platform.xml
	 * @param findFeatures if <code>true</code> will return paths to features, otherwise will return paths to plug-ins.
	 * @return a list of URL paths to plug-ins or features.  Possibly empty if the platform.xml had no entries or the default directory had no valid files
	 */
	public static URL[] getPlatformXMLPaths(String platformHome, boolean findFeatures) {
		File file = getPlatformFile(platformHome);
		if (file != null) {
			try {
				String value = new Path(platformHome).toFile().toURL().toExternalForm();
				System.setProperty(URL_PROPERTY, value);
				try {
					IPlatformConfiguration config = ConfiguratorUtils.getPlatformConfiguration(file.toURL());
					return getConfiguredSitesPaths(platformHome, config, findFeatures);
				} finally {
					System.setProperty(URL_PROPERTY, EMPTY_STRING);
				}
			} catch (MalformedURLException e) {
			} catch (IOException e) {
			}
		}
		return scanLocations(getSites(platformHome, findFeatures));
	}

	/**
	 * Returns a File object representing the platform.xml or null if the file cannot be found.
	 * @return File representing platform.xml or <code>null</code>
	 */
	private static File getPlatformFile(String platformHome) {
		String location = System.getProperty("org.eclipse.pde.platform_location"); //$NON-NLS-1$
		File file = null;
		if (location != null) {
			try {
				IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
				location = manager.performStringSubstitution(location);
				Path path = new Path(location);
				if (path.isAbsolute())
					file = path.toFile();
				else
					file = new File(platformHome, location);
				if (file.exists())
					return file;
			} catch (CoreException e) {
				PDECore.log(e);
			}
		}
		file = new File(platformHome, "configuration/org.eclipse.update/platform.xml"); //$NON-NLS-1$
		return file.exists() ? file : null;
	}

	private static URL[] getConfiguredSitesPaths(String platformHome, IPlatformConfiguration configuration, boolean features) {
		URL[] installPlugins = scanLocations(new File[] {new File(platformHome, features ? "features" : "plugins")}); //$NON-NLS-1$ //$NON-NLS-2$
		URL[] extensionPlugins = getExtensionPluginURLs(configuration, features);

		URL[] all = new URL[installPlugins.length + extensionPlugins.length];
		System.arraycopy(installPlugins, 0, all, 0, installPlugins.length);
		System.arraycopy(extensionPlugins, 0, all, installPlugins.length, extensionPlugins.length);
		return all;
	}

	/**
	 *
	 * @param config
	 * @param features true for features false for plugins
	 * @return URLs for features or plugins on the site
	 */
	private static URL[] getExtensionPluginURLs(IPlatformConfiguration config, boolean features) {
		ArrayList<URL> extensionPlugins = new ArrayList<>();
		IPlatformConfiguration.ISiteEntry[] sites = config.getConfiguredSites();
		for (ISiteEntry site : sites) {
			URL url = site.getURL();
			if ("file".equalsIgnoreCase(url.getProtocol())) { //$NON-NLS-1$
				String[] entries;
				if (features)
					entries = site.getFeatures();
				else
					entries = site.getPlugins();
				for (String entry : entries) {
					try {
						extensionPlugins.add(new File(url.getFile(), entry).toURL());
					} catch (MalformedURLException e) {
					}
				}
			}
		}
		return extensionPlugins.toArray(new URL[extensionPlugins.size()]);
	}

	/**
	 * Scan given plugin/feature directories or jars for existence
	 * @param sites
	 * @return URLs to plugins/features
	 */
	public static URL[] scanLocations(File[] sites) {
		HashSet<URL> result = new HashSet<>();
		for (int i = 0; i < sites.length; i++) {
			if (!sites[i].exists())
				continue;
			File[] children = sites[i].listFiles();
			if (children != null) {
				for (File element : children) {
					try {
						result.add(element.toURL());
					} catch (MalformedURLException e) {
					}
				}
			}
		}
		return result.toArray(new URL[result.size()]);
	}

	public static boolean isDevLaunchMode() {
		if (Boolean.getBoolean("eclipse.pde.launch")) //$NON-NLS-1$
			return true;
		String[] args = Platform.getApplicationArgs();
		for (String arg : args) {
			if (arg.equals("-pdelaunch")) //$NON-NLS-1$
				return true;
		}
		return false;
	}

}
