/*******************************************************************************
 * 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.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);

		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("Skipping '" + ce.getName() + "': missing " + ATT_ID);
					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("Skipping '" + ELMT_URL + "': missing " + ATT_LOCATION);
					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(")", "\\)")
					.replace("*", ".*");
			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'");
				if (ql.commandSpec != null) {
					out.append(" id='").append(asCSSId(ql.commandSpec)).append("' ");
				}
				out.append(" href='");
				out.append(urlEncodedCommand);
				out.append("'>");
				if (ql.iconUrl != null) {
					out.append("<img class='background-image' src='").append(ql.iconUrl).append("'>");
				}
				out.append("\n<div class='link-extra-div'></div>\n"); // UNKNOWN
				out.append("<span class='link-label'>");
				out.append(ql.label);
				out.append("</span>");
				if (ql.description != null) {
					out.append("\n<p><span class='text'>");
					out.append(ql.description);
					out.append("</span></p>");
				}
				out.append("</a>");
			} 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");
		if (ql.resolution != null) {
			encoded += "&standby=" + ql.resolution;
		}
		return "http://org.eclipse.ui.intro/execute?command=" + encoded;
	}

	/**
	 * 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:")) {
			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());
		}
		try {
			File tempFile = File.createTempFile("qlink", "png");
			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),
				forCommand("org.eclipse.ui.cheatsheets.openCheatSheet"), forCommand("org.eclipse.ui.newWizard"),
				forCommand("org.eclipse.ui.file.import"),
				forCommand("org.eclipse.epp.mpc.ui.command.showMarketplaceWizard"),
				forCommand("org.eclipse.ui.edit.text.openLocalFile", Importance.LOW));
	}

	public void dispose() {
	}
}
