/*******************************************************************************
 * Copyright (c) 2016 Manumitting Technologies Inc 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:
 *     Manumitting Technologies Inc - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.intro.quicklinks;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.core.commands.CommandManager;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.SerializationException;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandImageService;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.internal.intro.impl.model.AbstractIntroPartImplementation;
import org.eclipse.ui.internal.intro.impl.model.IntroTheme;
import org.eclipse.ui.internal.intro.impl.util.Log;
import org.eclipse.ui.internal.menus.MenuHelper;
import org.eclipse.ui.intro.config.IIntroContentProvider;
import org.eclipse.ui.intro.config.IIntroContentProviderSite;
import org.eclipse.ui.services.IServiceLocator;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;

/**
 * An Intro content provider that populates a list of frequently-used commands
 * from an extension point. The appearance of these quicklinks is normally taken
 * from the command metadata, including the image icon, but can be tailored.
 * These tailorings can be made optional depending on the current theme.
 *
 * This implementation is still experimental and subject to change. Feedback
 * welcome as a <a href="http://eclip.se/9f">bug report on the Eclipse Bugzilla
 * against Platform/User Assistance</a>.
 */
@SuppressWarnings("restriction")
public class QuicklinksViewer implements IIntroContentProvider {

	/** Represents the importance of an element */
	enum Importance {
		HIGH("high", 0), MEDIUM("medium", 1), LOW("low", 2); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		String id;
		int level;

		Importance(String text, int importance) {
			this.id = text;
			this.level = importance;
		}

		public static Importance forId(String id) {
			for (Importance i : values()) {
				if (i.id.equals(id)) {
					return i;
				}
			}
			return LOW;
		}
	}

	/** Model holding the relevant attributes of a Quicklink element */
	class Quicklink implements Comparable<Quicklink> {
		String commandSpec;
		String url;
		String label;
		String description;
		String iconUrl;
		Importance importance = Importance.MEDIUM;
		long rank;
		String resolution;

		public Quicklink() {
		}

		@Override
		public int compareTo(Quicklink b) {
			int impA = this.importance.level;
			int impB = b.importance.level;
			if (impA != impB) {
				return impA - impB;
			}
			long diff = this.rank - b.rank;
			if (diff > 0) {
				return 1;
			}
			if (diff < 0) {
				return -1;
			}
			return 0;
		}
	}

	/**
	 * Responsible for retrieving Quicklinks and applying any icon overrides
	 */
	class ModelReader implements Supplier<List<Quicklink>> {
		private static final String QL_EXT_PT = "org.eclipse.ui.intro.quicklinks"; //$NON-NLS-1$
		private static final String ELMT_COMMAND = "command"; //$NON-NLS-1$
		private static final String ATT_ID = "id"; //$NON-NLS-1$
		private static final String ELMT_URL = "url"; //$NON-NLS-1$
		private static final String ATT_LOCATION = "location"; //$NON-NLS-1$

		private static final String ELMT_OVERRIDE = "override"; //$NON-NLS-1$
		private static final String ATT_COMMANDID = "command"; //$NON-NLS-1$
		private static final String ATT_THEME = "theme"; //$NON-NLS-1$

		private static final String ATT_LABEL = "label"; //$NON-NLS-1$
		private static final String ATT_DESCRIPTION = "description"; //$NON-NLS-1$
		private static final String ATT_ICON = "icon"; //$NON-NLS-1$
		private static final String ATT_IMPORTANCE = "importance"; //$NON-NLS-1$
		private static final String ATT_RESOLUTION = "resolution"; //$NON-NLS-1$

		/** commandSpec/url &rarr; quicklink */
		private Map<String, Quicklink> quicklinks = new LinkedHashMap<>();
		/** bundle symbolic name &rarr; bundle id */
		private Map<String, Long> bundleIds;
		private Bundle[] bundles;

		/**
		 * Return the list of configured {@link Quicklink} that can be found.
		 *
		 * @return
		 */
		public List<Quicklink> get() {
			IExtension extensions[] = getExtensions(QL_EXT_PT);

			// Process definitions from the product bundle first
			Bundle productBundle = Platform.getProduct().getDefiningBundle();
			if(productBundle != null) {
				for (IExtension ext : extensions) {
					if (productBundle.getSymbolicName().equals(ext.getNamespaceIdentifier())) {
						for (IConfigurationElement ce : ext.getConfigurationElements()) {
							processDefinition(ce);
						}
					}
				}
			}

			for (IExtension ext : extensions) {
				if (productBundle == null || !productBundle.getSymbolicName().equals(ext.getNamespaceIdentifier())) {
					for (IConfigurationElement ce : ext.getConfigurationElements()) {
						processDefinition(ce);
					}
				}
			}

			// Now process all command overrides
			for (IExtension ext : extensions) {
				for (IConfigurationElement ce : ext.getConfigurationElements()) {
					if (!ELMT_OVERRIDE.equals(ce.getName())) {
						continue;
					}
					String theme = ce.getAttribute(ATT_THEME);
					String commandSpecPattern = ce.getAttribute(ATT_COMMANDID);
					String icon = ce.getAttribute(ATT_ICON);
					if (theme != null && icon != null && Objects.equals(theme, getCurrentThemeId())
							&& commandSpecPattern != null) {
						findMatchingQuicklinks(commandSpecPattern)
								.forEach(ql -> ql.iconUrl = getImageURL(ce, ATT_ICON));
					}
				}
			}
			return new ArrayList<>(quicklinks.values());
		}

		private void processDefinition(IConfigurationElement ce) {
			if (!ELMT_COMMAND.equals(ce.getName()) && !ELMT_URL.equals(ce.getName())) {
				return;
			}

			String key = null;
			Quicklink ql = new Quicklink();
			if (ELMT_COMMAND.equals(ce.getName())) {
				key = ce.getAttribute(ATT_ID);
				if (key == null) {
					Log.warning(NLS.bind("Skipping '{0}': missing {1}", ce.getName(), ATT_ID)); //$NON-NLS-1$
					return;
				}
				ql.commandSpec = key;
				ql.label = ce.getAttribute(ATT_LABEL);
				ql.description = ce.getAttribute(ATT_DESCRIPTION);
				ql.iconUrl = getImageURL(ce, ATT_ICON);
			} else if (ELMT_URL.equals(ce.getName())) {
				key = ce.getAttribute(ATT_LOCATION);
				if (key == null) {
					Log.warning(NLS.bind("Skipping '{0}': missing {1}", ELMT_URL, ATT_LOCATION)); //$NON-NLS-1$
					return;
				}
				ql.url = key;
				ql.label = ce.getAttribute(ATT_LABEL);
				ql.description = ce.getAttribute(ATT_DESCRIPTION);
				ql.iconUrl = getImageURL(ce, ATT_ICON);
			}
			ql.rank = getRank(ce.getContributor().getName());
			if (ce.getAttribute(ATT_IMPORTANCE) != null) {
				ql.importance = Importance.forId(ce.getAttribute(ATT_IMPORTANCE));
			}
			if (ce.getAttribute(ATT_RESOLUTION) != null) {
				ql.resolution = ce.getAttribute(ATT_RESOLUTION);
			}
			// discard if already seen
			quicklinks.putIfAbsent(key, ql);
		}

		/**
		 * Find {@link Quicklink}s whose {@code commandSpec} matches the simple
		 * wildcard pattern in {@code commandSpecPattern}
		 *
		 * @param commandSpecPattern
		 *            a simple wildcard pattern supporting *, ?
		 * @return the set of matching Quicklinks
		 */
		private Stream<Quicklink> findMatchingQuicklinks(String commandSpecPattern) {
			// transform simple wildcards into regexp
			String regexp = commandSpecPattern.replace(".", "\\.").replace("(", "\\(").replace(")", "\\)") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
					.replace("*", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
			final Pattern pattern = Pattern.compile(regexp);
			return quicklinks.values().stream().filter(
					ql -> ql.commandSpec != null && (commandSpecPattern.equals(ql.commandSpec)
							|| pattern.matcher(ql.commandSpec).matches()));
		}

		private IExtension[] getExtensions(String extPtId) {
			IExtensionRegistry registry = locator.getService(IExtensionRegistry.class);
			IExtensionPoint extPt = registry.getExtensionPoint(extPtId);
			return extPt == null ? new IExtension[0] : extPt.getExtensions();
		}


		private long getRank(String bundleSymbolicName) {
			if (bundleIds == null) {
				Bundle bundle = FrameworkUtil.getBundle(getClass());
				bundleIds = new HashMap<>();
				bundles = bundle.getBundleContext().getBundles();
			}
			return bundleIds.computeIfAbsent(bundleSymbolicName, bsn -> {
				for (Bundle b : bundles) {
					if (bsn.equals(b.getSymbolicName())
							&& (b.getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {
						return b.getBundleId();
					}
				}
				return Long.MAX_VALUE;
			});
		}

		/**
		 * @return URL to image, suitable for using in an external browser; may
		 *         be a <code>data:</code> URL; may be null
		 */
		private String getImageURL(IConfigurationElement ce, String attr) {
			String iconURL = MenuHelper.getIconURI(ce, attr);
			if (iconURL != null) {
				return asBrowserURL(iconURL);
			}
			return null;
		}
	}

	/** Source: http://stackoverflow.com/a/417184 */
	private static final int MAX_URL_LENGTH = 2083;

	private IIntroContentProviderSite site;
	private IServiceLocator locator;
	private CommandManager manager;
	private ICommandImageService images;
	private Supplier<List<Quicklink>> model;

	public void init(IIntroContentProviderSite site) {
		this.site = site;
		// IIntroContentProviderSite should provide services.
		if (site instanceof IServiceLocator) {
			this.locator = (IServiceLocator) site;
		} else if (site instanceof AbstractIntroPartImplementation) {
			this.locator = ((AbstractIntroPartImplementation) site).getIntroPart().getIntroSite();
		} else {
			this.locator = PlatformUI.getWorkbench();
		}
		manager = locator.getService(CommandManager.class);
		images = locator.getService(ICommandImageService.class);

		model = new ModelReader();
	}

	/**
	 * Find the current Welcome/Intro identifier
	 *
	 * @return the current identifier or {@code null} if no theme
	 */
	protected String getCurrentThemeId() {
		if (site instanceof AbstractIntroPartImplementation) {
			IntroTheme theme = ((AbstractIntroPartImplementation) site).getModel().getTheme();
			return theme.getId();
		}
		return null;
	}

	public void createContent(String id, PrintWriter out) {
		// Content is already embedded within a <div id="...">
		getQuicklinks().forEach(ql -> {
			try {
				// ah how lovely to embed HTML in code
				String urlEncodedCommand = asEmbeddedURL(ql);
				out.append("<a class='content-link'"); //$NON-NLS-1$
				if (ql.commandSpec != null) {
					out.append(" id='").append(asCSSId(ql.commandSpec)).append("' "); //$NON-NLS-1$ //$NON-NLS-2$
				}
				out.append(" href='"); //$NON-NLS-1$
				out.append(urlEncodedCommand);
				out.append("'>"); //$NON-NLS-1$
				if (ql.iconUrl != null) {
					out.append("<img class='background-image' src='").append(ql.iconUrl).append("'>"); //$NON-NLS-1$ //$NON-NLS-2$
				}
				out.append("\n<div class='link-extra-div'></div>\n"); // UNKNOWN //$NON-NLS-1$
				out.append("<span class='link-label'>"); //$NON-NLS-1$
				out.append(ql.label);
				out.append("</span>"); //$NON-NLS-1$
				if (ql.description != null) {
					out.append("\n<p><span class='text'>"); //$NON-NLS-1$
					out.append(ql.description);
					out.append("</span></p>"); //$NON-NLS-1$
				}
				out.append("</a>"); //$NON-NLS-1$
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		});
	}

	private String asEmbeddedURL(Quicklink ql) throws UnsupportedEncodingException {
		if (ql.url != null) {
			return ql.url;
		}
		String encoded = URLEncoder.encode(ql.commandSpec, "UTF-8"); //$NON-NLS-1$
		if (ql.resolution != null) {
			encoded += "&standby=" + ql.resolution; //$NON-NLS-1$
		}
		return "http://org.eclipse.ui.intro/execute?command=" + encoded; //$NON-NLS-1$
	}

	/**
	 * Transform the Eclipse Command identifier (with dots) to a CSS-compatible
	 * class
	 */
	private String asCSSId(String commandSpec) {
		int indexOf = commandSpec.indexOf('(');
		if (indexOf > 0) {
			commandSpec = commandSpec.substring(0, indexOf);
		}
		return commandSpec.replace('.', '_');
	}

	/**
	 * Rewrite or possible extract the icon at the given URL to a stable URL
	 * that can be embedded in HTML and rendered in a browser. May create
	 * temporary files that will be cleaned up on exit.
	 *
	 * @param iconURL
	 * @return stable URL
	 */
	private String asBrowserURL(String iconURL) {
		if (iconURL.startsWith("file:") || iconURL.startsWith("http:")) { //$NON-NLS-1$ //$NON-NLS-2$
			return iconURL;
		}
		try {
			URL original = new URL(iconURL);
			URL toLocal = FileLocator.toFileURL(original);
			if (!toLocal.sameFile(original)) {
				return toLocal.toString();
			}
		} catch (IOException e1) {
			/* ignore */
		}

		// extract content
		try {
			return asDataURL(ImageDescriptor.createFromURL(new URL(iconURL)));
		} catch (MalformedURLException e) {
			// should probably log this
			return iconURL;
		}
	}

	/**
	 * Write out the image as a data: URL if possible or to the file-system.
	 *
	 * @param descriptor
	 * @return URL with the resulting image
	 */
	private String asDataURL(ImageDescriptor descriptor) {
		if (descriptor == null) {
			return null;
		}
		ImageData data = descriptor.getImageData();
		if (data == null) {
			return null;
		}
		ImageLoader loader = new ImageLoader();
		loader.data = new ImageData[] { data };

		ByteArrayOutputStream output = new ByteArrayOutputStream();
		loader.save(output, SWT.IMAGE_PNG);
		if (output.size() * 4 / 3 < MAX_URL_LENGTH) {
			// You'd think there was a more efficient way to do this...
			return "data:image/png;base64," + Base64.getEncoder().encodeToString(output.toByteArray()); //$NON-NLS-1$
		}
		try {
			File tempFile = File.createTempFile("qlink", "png"); //$NON-NLS-1$ //$NON-NLS-2$
			FileOutputStream fos = new FileOutputStream(tempFile);
			fos.write(output.toByteArray());
			fos.close();
			tempFile.deleteOnExit();
			return tempFile.toURI().toString();
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public void createContent(String id, Composite parent, FormToolkit toolkit) {
		Section section = toolkit.createSection(parent, Section.EXPANDED);
		TableViewer tableViewer = new TableViewer(toolkit.createTable(section, SWT.FULL_SELECTION));
		tableViewer.setLabelProvider(new URLLabelProvider() {
			@Override
			public String getText(Object element) {
				if (element instanceof Quicklink) {
					return ((Quicklink) element).label;
				}
				return super.getText(element);
			}

			@Override
			public Image getImage(Object element) {
				if (element instanceof Quicklink) {
					return super.getImage(((Quicklink) element).iconUrl);
				}
				return super.getImage(element);
			}
		});
		tableViewer.setContentProvider(new ArrayContentProvider());
		tableViewer.setInput(getQuicklinks().toArray());
	}

	private List<Quicklink> getQuicklinks() {
		List<Quicklink> links = model.get();
		if (links.isEmpty()) {
			links = generateDefaultQuicklinks();
		}
		return links.stream().filter(this::populateQuicklink).sorted(Quicklink::compareTo)
				.collect(Collectors.toList());
	}

	/**
	 * Attempt to populate common fields given other information. For commands,
	 * we look up information in the ICommandService and ICommandImageService.
	 * Return false if this quicklink cannot be found and should not be shown.
	 *
	 * @return true if should be included
	 */
	private boolean populateQuicklink(Quicklink ql) {
		if (ql.commandSpec == null) {
			// non-commmands are fine
			return true;
		}
		try {
			ParameterizedCommand pc = manager.deserialize(ql.commandSpec);
			if (!pc.getCommand().isDefined()) {
				// not an error: just not found
				return false;
			}
			if (ql.label == null) {
				ql.label = pc.getCommand().getName();
			}
			if (ql.description == null) {
				ql.description = pc.getCommand().getDescription();
			}
			if (ql.iconUrl == null && images != null) {
				ImageDescriptor descriptor = images.getImageDescriptor(pc.getId());
				if (descriptor != null) {
					String iconUrl = MenuHelper.getImageUrl(descriptor);
					ql.iconUrl = iconUrl != null ? asBrowserURL(iconUrl) : asDataURL(descriptor);
				}
			}
			return true;
		} catch (NotDefinedException | SerializationException e) {
			// exclude commands that don't exist or are mis-fashioned
			return false;
		}
	}

	/** Simplify creating a quicklink for a command */
	private Quicklink forCommand(String commandSpec) {
		Quicklink ql = new Quicklink();
		ql.commandSpec = commandSpec;
		return ql;
	}

	/** Simplify creating a quicklink for a command */
	private Quicklink forCommand(String commandSpec, Importance importance) {
		Quicklink ql = new Quicklink();
		ql.commandSpec = commandSpec;
		ql.importance = importance;
		return ql;
	}

	/**
	 * Return the default commands to be shown if there is no other content
	 * available
	 */
	private List<Quicklink> generateDefaultQuicklinks() {
		return Arrays.asList(forCommand("org.eclipse.oomph.setup.ui.questionnaire", Importance.HIGH), //$NON-NLS-1$
				forCommand("org.eclipse.ui.cheatsheets.openCheatSheet"), //$NON-NLS-1$
				forCommand("org.eclipse.ui.newWizard"), //$NON-NLS-1$
				forCommand("org.eclipse.ui.file.import"), //$NON-NLS-1$
				forCommand("org.eclipse.epp.mpc.ui.command.showMarketplaceWizard"), //$NON-NLS-1$
				forCommand("org.eclipse.ui.edit.text.openLocalFile", Importance.LOW)); //$NON-NLS-1$
	}

	public void dispose() {
	}
}
