/*******************************************************************************
 * Copyright (c) 2014 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()) {
			BufferedReader r = null;
			try {
				final InputStream s = new FileInputStream(f);
				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();
			} finally {
				if (r != null) {
					try {
						r.close();
					} catch (final IOException e) {
					}
				}
			}
		}
		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();

}
