/*******************************************************************************
 * Copyright (c) 2014, 2017 TwelveTone LLC 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:
 * Steven Spungin <steven@spungin.tv> - initial API and implementation, Bug 424730, Bug 435625, Bug 436133, Bug 436132,
 * Bug 436283, Bug 436281, Bug 443510
 * Fabian Miehe - Bug 440327
 *******************************************************************************/

package org.eclipse.e4.tools.emf.ui.internal.common.resourcelocator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.e4.tools.emf.ui.common.IClassContributionProvider;
import org.eclipse.e4.tools.emf.ui.common.IClassContributionProvider.ContributionData;
import org.eclipse.e4.tools.emf.ui.common.IModelElementProvider;
import org.eclipse.e4.tools.emf.ui.common.IProviderStatusCallback;
import org.eclipse.e4.tools.emf.ui.common.ProviderStatus;
import org.eclipse.e4.tools.emf.ui.common.ResourceSearchScope;
import org.eclipse.e4.tools.emf.ui.internal.common.ClassContributionCollector;
import org.eclipse.e4.tools.emf.ui.internal.common.component.dialogs.FilteredContributionDialog;
import org.eclipse.e4.tools.emf.ui.internal.common.component.tabs.empty.E;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.pde.core.plugin.IPluginBase;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.internal.core.PDECore;
import org.eclipse.pde.internal.core.TargetPlatformHelper;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

/**
 * A contribution collector encompassing the current target platform.<br />
 * Uses filter for bundle, package, and location filtering.<br />
 * This implementation finds resources based on file names, not by parsing file
 * contents.
 *
 * @author Steven Spungin
 *
 */
public abstract class TargetPlatformContributionCollector extends ClassContributionCollector {

	CopyOnWriteArrayList<Entry> cacheEntry = new CopyOnWriteArrayList<>();
	HashSet<String> cacheBundleId = new HashSet<>();
	HashSet<String> cachePackage = new HashSet<>();
	HashSet<String> cacheLocation = new HashSet<>();
	private Pattern patternFile;
	protected String cacheName;
	protected boolean stopFiltering;

	static class Entry {
		String name;
		String path;
		String installLocation;
		String relativePath;
		String bundleSymName;
		String pakage;
	}

	@SuppressWarnings("unused")
	private TargetPlatformContributionCollector() {
	}

	protected TargetPlatformContributionCollector(String cacheName) {

		this.cacheName = cacheName;
		patternFile = getFilePattern();

		addContributor(new IClassContributionProvider() {

			@Override
			public void findContribution(Filter filter, ContributionResultHandler handler) {

				final Pattern patternName = Pattern.compile(filter.namePattern, Pattern.CASE_INSENSITIVE);

				reloadCache(false, filter.getProviderStatusCallback());

				int maxResults = filter.maxResults;
				if (maxResults == 0) {
					maxResults = 100;
				}

				int found = 0;
				boolean more = false;

				stopFiltering = false;
				for (final Entry e : cacheEntry) {
					if (stopFiltering) {
						break;
					}
					final IProgressMonitor monitor = filter.getProgressMonitor();
					if (monitor != null) {
						if (monitor.isCanceled()) {
							stopFiltering = true;
							break;
						}
						monitor.subTask(Messages.TargetPlatformContributionCollector_Searching
								+ " " + e.installLocation); //$NON-NLS-1$
					}

					if (E.notEmpty(filter.getBundles())) {
						if (!filter.getBundles().contains(e.bundleSymName)) {
							continue;
						}
					}
					if (E.notEmpty(filter.getPackages())) {
						if (!filter.getPackages().contains(e.pakage)) {
							continue;
						}
					}
					if (E.notEmpty(filter.getLocations())) {
						boolean locationFound = false;
						for (final String location : filter.getLocations()) {
							if (e.installLocation.startsWith(location)) {
								locationFound = true;
								break;
							}
						}
						if (!locationFound) {
							continue;
						}
					}
					if (filter.isIncludeNonBundles() == false) {
						if (e.bundleSymName == null) {
							continue;
						}
					}
					if (filter.getSearchScope().contains(ResourceSearchScope.WORKSPACE)) {
						if (filter.project != null) {
							final IWorkspace workspace = filter.project.getWorkspace();
							boolean fnd = false;
							for (final IProject project : workspace.getRoot().getProjects()) {
								// String path =
								// project.getLocationURI().getPath();
								final String path = project.getName();
								if (e.installLocation.contains(path)) {
									fnd = true;
									break;
								}
							}
							if (!fnd) {
								continue;
							}
						}
					}

					final Matcher m = patternName.matcher(e.name);
					if (m.find()) {
						found++;
						if (found > maxResults) {
							more = true;
							handler.moreResults(ContributionResultHandler.MORE_UNKNOWN, filter);
							break;
						}
						handler.result(makeData(e));
					}

				}
				if (!more) {
					if (stopFiltering) {
						handler.moreResults(ContributionResultHandler.MORE_CANCELED, filter);
					} else {
						handler.moreResults(0, filter);
					}
				}
			}
		});

		addModelElementContributor(new IModelElementProvider() {

			@Override
			public void getModelElements(Filter filter, ModelResultHandler handler) {
				// TODO Auto-generated method stub
			}

			@Override
			public void clearCache() {
				stopFiltering = true;
				cacheEntry.clear();
				cacheBundleId.clear();
				cachePackage.clear();
				cacheLocation.clear();
				outputDirectories.clear();
			}
		});
	}

	protected ContributionData makeData(Entry e) {
		// If class is in a java project, strip the source directory
		// String path = e.path;// .replace("/", ".") + e.name;
		// path = stripSourceDirectory(path, e.installLocation);
		IPath ip = Path.fromOSString(e.path);
		ip = ip.addTrailingSeparator().makeRelative();
		ip = ip.append(e.name);
		final String className = ip.toOSString().replace(File.separatorChar, '.');
		final ContributionData data = new ContributionData(e.bundleSymName, className, "Java", e.installLocation); //$NON-NLS-1$
		data.installLocation = e.installLocation;
		data.resourceRelativePath = e.relativePath;
		return data;
	}

	/**
	 *
	 * @return A copy of the bundle IDs in the cache.
	 */
	public Collection<String> getBundleIds() {
		reloadCache(false, null);
		return new ArrayList<>(cacheBundleId);
	}

	/**
	 *
	 * @return A copy of the bundle IDs in the cache.
	 */
	public Collection<String> getPackages() {
		reloadCache(false, null);
		return new ArrayList<>(cachePackage);
	}

	/**
	 *
	 * @return A copy of the bundle IDs in the cache.
	 */
	public Collection<String> getLocations() {
		reloadCache(false, null);
		return new ArrayList<>(cacheLocation);
	}

	/**
	 * Ensures the cache is loaded. By default it is loaded on first access, and
	 * kept static until forced to reloaded.
	 *
	 * @param force
	 *            true to force reload the cache
	 * @param providerStatusCallback
	 */
	private void reloadCache(boolean force, final IProviderStatusCallback providerStatusCallback) {
		if (cacheEntry.isEmpty() || force) {
			if (providerStatusCallback != null) {
				providerStatusCallback.onStatusChanged(ProviderStatus.INITIALIZING);
			}
			cacheEntry.clear();
			cacheBundleId.clear();
			cachePackage.clear();
			cacheLocation.clear();
			outputDirectories.clear();

			final Job job = new Job(Messages.TargetPlatformContributionCollector_BuildTargetPlatformIndex) {

				@Override
				protected IStatus run(IProgressMonitor monitor) {
					// load workspace projects
					final IProject[] projects = PDECore.getWorkspace().getRoot().getProjects();
					final IPluginModelBase[] models = TargetPlatformHelper.getPDEState().getTargetModels();
					final int total = projects.length + models.length;
					monitor.beginTask(Messages.TargetPlatformContributionCollector_updatingTargetPlatformCache
							+ cacheName + ")", total); //$NON-NLS-1$

					for (final IProject pj : projects) {
						if (monitor.isCanceled()) {
							break;
						}
						final String rootDirectory = pj.getLocation().toOSString();
						monitor.subTask(rootDirectory);
						monitor.worked(1);
						TargetPlatformContributionCollector.this
						.visit(monitor, FilteredContributionDialog.getBundle(rootDirectory), rootDirectory,
								new File(rootDirectory));
					}

					// load target platform bundles
					for (final IPluginModelBase pluginModelBase : models) {
						monitor.subTask(pluginModelBase.getPluginBase().getId());
						monitor.worked(1);
						if (monitor.isCanceled()) {
							break;
						}

						final IPluginBase pluginBase = pluginModelBase.getPluginBase();
						if (pluginBase == null) {
							// bundle = getBundle(new File())
							continue;
						}
						URL url;
						try {
							final String installLocation = pluginModelBase.getInstallLocation();
							if (installLocation.endsWith(".jar")) { //$NON-NLS-1$
								url = new URL("file://" + installLocation); //$NON-NLS-1$
								final ZipInputStream zis = new ZipInputStream(url.openStream());
								while (true) {
									final ZipEntry entry = zis.getNextEntry();
									if (entry == null) {
										break;
									}
									final String name2 = entry.getName();
									if (shouldIgnore(name2)) {
										continue;
									}
									final Matcher m = patternFile.matcher(name2);
									if (m.matches()) {
										final Entry e = new Entry();
										e.installLocation = installLocation;
										cacheLocation.add(installLocation);
										e.name = m.group(2);
										e.path = m.group(1);
										if (e.path != null) {
											e.pakage = e.path.replace("/", "."); //$NON-NLS-1$ //$NON-NLS-2$
											if (e.pakage.startsWith(".")) { //$NON-NLS-1$
												e.pakage = e.pakage.substring(1);
											}
											if (e.pakage.endsWith(".")) { //$NON-NLS-1$
												e.pakage = e.pakage.substring(0, e.pakage.length() - 1);
											}
										} else {
											e.pakage = ""; //$NON-NLS-1$
										}
										cachePackage.add(e.pakage);

										e.bundleSymName = pluginBase.getId();
										if (e.path == null) {
											e.path = ""; //$NON-NLS-1$
										}
										cacheEntry.add(e);
										cacheBundleId.add(pluginBase.getId());

										//
										// System.out.println(group
										// + " -> "
										// +
										// m.group(2));
									}
								}
							} else {
								// not a jar file
								final String bundle = getBundle(new File(installLocation));
								if (bundle != null) {
									visit(monitor, bundle, installLocation, new File(installLocation));
								}
							}
						} catch (final MalformedURLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (final IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					monitor.done();
					if (monitor.isCanceled()) {
						if (providerStatusCallback != null) {
							providerStatusCallback.onStatusChanged(ProviderStatus.CANCELLED);
						}
						return Status.CANCEL_STATUS;
					}
					if (providerStatusCallback != null) {
						providerStatusCallback.onStatusChanged(ProviderStatus.READY);
					}
					return Status.OK_STATUS;
				}
			};
			job.schedule();

			// User Job will not display dialog if called from a modal dialog,
			// so we wrap a plain ol' job in a ProgressMonitorDialog
			Display.getDefault().syncExec(new Runnable() {

				boolean runInBackground = false;

				@Override
				public void run() {
					final ProgressMonitorDialog dlg = new ProgressMonitorDialog(Display.getDefault().getActiveShell()) {

						@Override
						protected Control createContents(Composite parent) {
							// TODO odd this is not a bean.
							final Composite ret = (Composite) super.createContents(parent);
							final Label label = new Label(ret, SWT.NONE);
							label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false, 2, 1));
							label.setText(Messages.TargetPlatformContributionCollector_pleaseWait);

							return ret;
						}

						@Override
						protected void createButtonsForButtonBar(Composite parent) {
							final Button button = createButton(parent, 101,
									Messages.TargetPlatformContributionCollector_RunInBackground, false);
							// TODO JA
							button.addSelectionListener(new SelectionAdapter() {
								@Override
								public void widgetSelected(SelectionEvent e) {
									runInBackground = true;
								}
							});
							super.createButtonsForButtonBar(parent);

							// Do not use arrow cursor until calling super
							// TODO ProgressMonitorDialog should encapsulate
							// arrowCurson
							button.setCursor(arrowCursor);
						}

						@Override
						protected void cancelPressed() {
							job.cancel();
						}
					};
					try {
						dlg.run(true, true, new IRunnableWithProgress() {

							@Override
							public void run(final IProgressMonitor monitor) throws InvocationTargetException,
							InterruptedException {
								monitor
								.beginTask(
										Messages.TargetPlatformContributionCollector_WaitingForTargetPlatformIndexingToComplete,
										IProgressMonitor.UNKNOWN);
								while (job.getState() == Job.RUNNING && !runInBackground) {
									Thread.sleep(100);
								}
								monitor.done();
							}
						});
					} catch (final InvocationTargetException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					} catch (final InterruptedException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}

			});
		}
	}

	// @Refactor
	static public String getBundle(File file) {
		if (file.isDirectory() == false) {
			return null;
		}

		final File f = new File(file, "META-INF/MANIFEST.MF"); //$NON-NLS-1$

		if (f.exists() && f.isFile()) {
			try (final InputStream s = new FileInputStream(f);
					BufferedReader r = new BufferedReader(new InputStreamReader(s))) {
				String line;
				while ((line = r.readLine()) != null) {
					if (line.startsWith("Bundle-SymbolicName:")) { //$NON-NLS-1$
						final int start = line.indexOf(':');
						int end = line.indexOf(';');
						if (end == -1) {
							end = line.length();
						}
						return line.substring(start + 1, end).trim();
					}
				}
			} catch (final IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	protected void visit(IProgressMonitor monitor, String bundleName, String installLocation, File file) {
		for (final File fChild : file.listFiles()) {
			if (monitor.isCanceled()) {
				break;
			}
			if (fChild.isDirectory()) {
				visit(monitor, bundleName, installLocation, fChild);
			} else {
				String name2 = fChild.getAbsolutePath().substring(installLocation.length() + 1);
				name2 = stripOutputDirectory(name2, installLocation);
				if (shouldIgnore(name2)) {
					continue;
				}
				final Matcher m = patternFile.matcher(name2);
				if (m.matches()) {
					final Entry e = new Entry();
					e.installLocation = installLocation;
					cacheLocation.add(installLocation);
					e.name = m.group(2);
					if (e.name.contains("$")) { //$NON-NLS-1$
						continue;
					}
					e.path = m.group(1);
					if (e.path != null) {
						e.pakage = e.path.replace("/", "."); //$NON-NLS-1$ //$NON-NLS-2$
						if (e.pakage.startsWith(".")) { //$NON-NLS-1$
							e.pakage = e.pakage.substring(1);
						}
						if (e.pakage.endsWith(".")) { //$NON-NLS-1$
							e.pakage = e.pakage.substring(0, e.pakage.length() - 1);
						}
					} else {
						e.pakage = ""; //$NON-NLS-1$
					}
					if (e.path == null) {
						e.path = ""; //$NON-NLS-1$
					}
					e.relativePath = Path
							.fromOSString(file.getAbsolutePath().replace(e.installLocation, "")).makeRelative().toOSString(); //$NON-NLS-1$

					e.bundleSymName = bundleName;
					// TODO we need project to strip source paths.
					// e.pakage = e.pakage.replaceAll("^bin.", "");
					cachePackage.add(e.pakage);
					cacheEntry.add(e);
					if (bundleName != null) {
						cacheBundleId.add(bundleName);
					}
				}
			}
		}

	}

	static private String stripOutputDirectory(String path, String installLocation) {
		if (installLocation.matches(".*\\.jar")) { //$NON-NLS-1$
			return path;
		}
		for (final String sourceDirectory : getOutputDirectories(installLocation)) {
			if (path.startsWith(sourceDirectory)) {
				path = path.substring(sourceDirectory.length());
				break;
			}
		}
		return path;
	}

	/**
	 * A cache of the output directories for install locations (if install
	 * location has a classpath file with appropriate output entries)
	 */
	static private HashMap<String, List<String>> outputDirectories = new HashMap<>();

	// Returns the Eclipse output directories for an install location. The
	// directories are relative to the install location.
	// <classpathentry kind="output" path="bin"/>
	static private List<String> getOutputDirectories(String installLocation) {
		List<String> ret = outputDirectories.get(installLocation);
		if (ret == null) {
			ret = new ArrayList<>();
			outputDirectories.put(installLocation, ret);
			try {
				final Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
						.parse(new File(installLocation + File.separator + ".classpath")); //$NON-NLS-1$
				final XPath xp = XPathFactory.newInstance().newXPath();
				final NodeList list = (NodeList) xp.evaluate(
						"//classpathentry[@kind='output']/@path", doc, XPathConstants.NODESET); //$NON-NLS-1$
				for (int i = 0; i < list.getLength(); i++) {
					final String value = list.item(i).getNodeValue();
					ret.add(value);
				}
			} catch (final Exception e) {
			}
		}
		return ret;
	}

	protected boolean shouldIgnore(String name) {
		return false;
	}

	protected abstract Pattern getFilePattern();

}
