/*******************************************************************************
 * Copyright (c) 2009, 2017 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.ui.intro.contentproviders;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.internal.intro.impl.IntroPlugin;
import org.eclipse.ui.internal.intro.impl.Messages;
import org.eclipse.ui.intro.config.IIntroContentProvider;
import org.eclipse.ui.intro.config.IIntroContentProviderSite;
import org.eclipse.ui.intro.config.IIntroURL;
import org.eclipse.ui.intro.config.IntroURLFactory;
import org.osgi.framework.Bundle;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * A content provider which allows a news reader to be included in dynamic intro content.
 * <p>
 * The id for the contentProvider tag must consist of the following attributes. Each of these attributes must be separated by '##'.
 * <ul>
 * <TABLE CELLPADDING=6 FRAME=BOX>
 *
 * <THEAD>
 * <TR> <TH>Attribute</TH>     <TH>Description</TH>                         </TR>
 * </THEAD>
 *
 * <TBODY>
 * <TR> <TD>url</TD>           <TD>RSS news feed url</TD>                   </TR>
 * <TR> <TD>welcome_items</TD> <TD>Number of news feed to be displayed</TD> </TR>
 * <TR> <TD>no_news_url</TD>   <TD>Alternative url for news feed</TD>       </TR>
 * <TR> <TD>no_news_text</TD>  <TD>Text for the alternative url</TD>        </TR>
 * </TBODY>
 *
 * </TABLE>
 * </ul>
 * For example:
 * <p>
 * &lt;contentProvider <br>
 * <ul>
 * id=&quot;url=http://www.eclipse.org/home/eclipsenews.rss##welcome_items=5##no_news_url=http://www.eclipse.org/community/##no_news_text=Welcome to the Eclipse Community Page&quot; <br>
 * pluginId=&quot;org.eclipse.ui.intro&quot; <br>
 * class=&quot;org.eclipse.ui.intro.contentproviders.EclipseRSSViewer&quot;&gt; <br>
 * </ul>
 * &lt;/contentProvider&gt;
 * </p>
 *
 * @since 3.4
 */

public class EclipseRSSViewer implements IIntroContentProvider {

	private final int SOCKET_TIMEOUT = 6000; //milliseconds

	private static final String INTRO_SHOW_IN_BROWSER = "http://org.eclipse.ui.intro/openBrowser?url="; //$NON-NLS-1$

	private static final String HREF_BULLET = "bullet"; //$NON-NLS-1$

	private Map<String, String> params;

	private IIntroContentProviderSite site;

	private boolean disposed;

	private String id;

	private List<NewsItem> items;

	private Composite parent;

	private FormToolkit toolkit;

	private FormText formText;

	private Image bulletImage;

	private boolean threadRunning = false;

	/**
	 * Initialize the content provider
	 * @param site an object which allows rcontainer reflows to be requested
	 */
	@Override
	public void init(IIntroContentProviderSite site) {
		this.site = site;
		refresh();
	}

	/**
	 * Create the html content for this newsreader
	 * @param id
	 * @param out a writer where the html will be written
	 */
	@Override
	public void createContent(String id, PrintWriter out) {
		if (disposed)
			return;
		this.id = id;
		params = setParams(id);


		if (items==null)
			createNewsItems();

		if (items == null || threadRunning) {
			out.print("<p class=\"status-text\">"); //$NON-NLS-1$
			out.print(Messages.RSS_Loading);
			out.println("</p>"); //$NON-NLS-1$
		} else {
			if (items.size() > 0) {
				out.println("<ul id=\"news-feed\" class=\"news-list\">"); //$NON-NLS-1$
				for (NewsItem item : items) {
					out.print("<li>"); //$NON-NLS-1$
					out.print("<a class=\"topicList\" href=\""); //$NON-NLS-1$
					out.print(createExternalURL(item.url));

					out.print("\">"); //$NON-NLS-1$
					out.print(item.label);
					out.print("</a>"); //$NON-NLS-1$
					out.print("</li>\n"); //$NON-NLS-1$
				}
				out.println("</ul>"); //$NON-NLS-1$
			} else {
				out.print("<p class=\"status-text\">"); //$NON-NLS-1$
				out.print(Messages.RSS_No_news_please_visit);
				out.print(" <a href=\""); //$NON-NLS-1$
				out.print(createExternalURL(getParameter("no_news_url"))); //$NON-NLS-1$
				out.print("\">"); //$NON-NLS-1$
				out.print(getParameter("no_news_text")); //$NON-NLS-1$
				out.print("</a>"); //$NON-NLS-1$
				out.println("</p>"); //$NON-NLS-1$
			}
			URL url = null;
			try {
				url = new URL(getParameter("url")); //$NON-NLS-1$
			} catch (MalformedURLException e) {
				IntroPlugin.logError("Bad URL: "+url, e); //$NON-NLS-1$
			}
			if (url != null) {
				out.println("<p><span class=\"rss-feed-link\">"); //$NON-NLS-1$
				out.println("<a href=\""); //$NON-NLS-1$
				out.println(createExternalURL(url.toString()));
				out.println("\">"); //$NON-NLS-1$
				out.println(Messages.RSS_Subscribe);
				out.println("</a>"); //$NON-NLS-1$
				out.println("</span></p>"); //$NON-NLS-1$
			}
		}
	}

	/**
	 * Create widgets to display the newsreader when using the SWT presentation
	 */
	@Override
	public void createContent(String id, Composite parent, FormToolkit toolkit) {
		if (disposed)
			return;
		this.id = id;
		params = setParams(id);

		if (formText == null) {
			// a one-time pass
			formText = toolkit.createFormText(parent, true);
			formText.addHyperlinkListener(new HyperlinkAdapter() {
				@Override
				public void linkActivated(HyperlinkEvent e) {
					doNavigate((String) e.getHref());
				}
			});
			bulletImage = createImage(new Path("icons/arrow.png")); //$NON-NLS-1$
			if (bulletImage != null)
				formText.setImage(HREF_BULLET, bulletImage);
			this.parent = parent;
			this.toolkit = toolkit;
			this.id = id;
			params = setParams(id);

		}

		StringBuilder buffer = new StringBuilder();
		buffer.append("<form>"); //$NON-NLS-1$


		if (items==null)
			createNewsItems();

		if (items == null || threadRunning) {
			buffer.append("<p>"); //$NON-NLS-1$
			buffer.append(Messages.RSS_Loading);
			buffer.append("</p>"); //$NON-NLS-1$
		} else {
			if (items.size() > 0) {
				for (int i = 0; i < items.size(); i++) {
					NewsItem item = items.get(i);
					buffer.append("<li style=\"image\" value=\""); //$NON-NLS-1$
					buffer.append(HREF_BULLET);
					buffer.append("\">"); //$NON-NLS-1$
					buffer.append("<a href=\""); //$NON-NLS-1$
					buffer.append(createExternalURL(item.url));
					buffer.append("\">"); //$NON-NLS-1$
					buffer.append(item.label);
					buffer.append("</a>"); //$NON-NLS-1$
					buffer.append("</li>"); //$NON-NLS-1$

				}
			} else {

				buffer.append("<p>"); //$NON-NLS-1$
				buffer.append(Messages.RSS_No_news);
				buffer.append("</p>"); //$NON-NLS-1$
			}
		}

		buffer.append("</form>"); //$NON-NLS-1$

		String text = buffer.toString();
		text = text.replaceAll("&{1}", "&amp;"); //$NON-NLS-1$ //$NON-NLS-2$
		formText.setText(text, true, false);
	}


	private String createExternalURL(String url) {
		try {
			return INTRO_SHOW_IN_BROWSER + URLEncoder.encode(url, "UTF-8"); //$NON-NLS-1$
		} catch (UnsupportedEncodingException e) {
			return INTRO_SHOW_IN_BROWSER + url;
		}
	}

	@Override
	public void dispose() {
		if (bulletImage != null) {
			bulletImage.dispose();
			bulletImage = null;
		}
		disposed = true;
	}

	/**
	 * Method is responsible for gathering RSS data.
	 *
	 * Kicks off 2 threads:
	 *
	 * 	The first (ContentThread) is to actually query the feeds URL to find RSS entries.
	 *  When it finishes, it calls a refresh to display the entires it found (if any).
	 *
	 *  [Esc RATLC00319786]
	 *  The second (TimeoutThread) waits for SOCKET_TIMEOUT ms to see if the content thread
	 *  has finished reading RSS.  If it has finished, nothing further happens.  If it has
	 *  not finished, the TimeoutThread sets the threadRunning boolean to false and refreshes
	 *  the page (basically telling the UI that no content could be found, and removes
	 *  the 'Loading...' text).
	 *
	 */
	private void createNewsItems() {

		ContentThread contentThread = new ContentThread();
		contentThread.start();
		TimeoutThread timeThread = new TimeoutThread();
		timeThread.start();
	}

	/**
	 * Reflows the page using an UI thread.
	 */
	private void refresh()
	{
		Thread newsWorker = new Thread(new NewsFeed());
		newsWorker.start();
	}

	private Image createImage(IPath path) {
		Bundle bundle = Platform.getBundle(IntroPlugin.PLUGIN_ID);
		URL url = FileLocator.find(bundle, path, null);
		try {
			url = FileLocator.toFileURL(url);
			ImageDescriptor desc = ImageDescriptor.createFromURL(url);
			return desc.createImage();
		} catch (IOException e) {
			return null;
		}
	}

	private void doNavigate(final String url) {
		BusyIndicator.showWhile(PlatformUI.getWorkbench().getDisplay(),
				() -> {
					IIntroURL introUrl = IntroURLFactory
							.createIntroURL(url);
					if (introUrl != null) {
						// execute the action embedded in the IntroURL
						introUrl.execute();
						return;
					}
					// delegate to the browser support
					openBrowser(url);
				});
	}

	private void openBrowser(String href) {
		try {
			URL url = new URL(href);
			IWorkbenchBrowserSupport support = PlatformUI.getWorkbench()
					.getBrowserSupport();
			support.getExternalBrowser().openURL(url);
		} catch (PartInitException e) {
		} catch (MalformedURLException e) {
		}
	}

	static class NewsItem {
		String label;

		String url;

		void setLabel(String label) {
			this.label = label;
		}

		void setUrl(String url) {
			this.url = url;
		}
	}

	class NewsFeed implements Runnable {
		@Override
		public void run() {
			// important: don't do the work if the
			// part gets disposed in the process
			if (disposed)
				return;

			PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
				if (parent != null) {
					// we must recreate the content
					// for SWT because we will use
					// a gentle incremental reflow.
					// HTML reflow will simply reload the page.
					createContent(id, parent, toolkit);
//						reflow(formText);
				}
				site.reflow(EclipseRSSViewer.this, true);
			});
		}
	}

	/**
	 * Handles RSS XML and populates the items list with at most
	 * MAX_NEWS_ITEMS items.
	 */
	private class RSSHandler extends DefaultHandler {

		private static final String ELEMENT_RSS = "rss"; //$NON-NLS-1$
		private static final String ELEMENT_CHANNEL = "channel"; //$NON-NLS-1$
		private static final String ELEMENT_ITEM = "item"; //$NON-NLS-1$
		private static final String ELEMENT_TITLE = "title"; //$NON-NLS-1$
		private static final String ELEMENT_LINK = "link"; //$NON-NLS-1$

		private Stack<String> stack = new Stack<>();
		private StringBuilder buf;
		private NewsItem item;

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException {
			stack.push(qName);
			// it's a title/link in an item
			if ((ELEMENT_TITLE.equals(qName) || ELEMENT_LINK.equals(qName))
					&& (item != null)) {
				// prepare the buffer; we're expecting chars
				buf = new StringBuilder();
			}
			// it's an item in a channel in rss
			else if (ELEMENT_ITEM.equals(qName)
					&& (ELEMENT_CHANNEL.equals(stack.get(1)))
					&& (ELEMENT_RSS.equals(stack.get(0)))
					&& (stack.size() == 3)
					&& (items.size() < Integer
							.parseInt(getParameter("welcome_items")))) { //$NON-NLS-1$

				// prepare the item
				item = new NewsItem();
			}
		}

		@Override
		public void endElement(String uri, String localName, String qName)
				throws SAXException {
			stack.pop();
			if (item != null) {
				if (buf != null) {
					if (ELEMENT_TITLE.equals(qName)) {
						item.setLabel(buf.toString().trim());
						buf = null;
					} else if (ELEMENT_LINK.equals(qName)) {
						item.setUrl(buf.toString().trim());
						buf = null;
					}
				} else {
					if (ELEMENT_ITEM.equals(qName)) {
						// ensure we have a valid item
						if (item.label != null && item.label.length() > 0
								&& item.url != null && item.url.length() > 0) {
							items.add(item);
						}
						item = null;
					}
				}
			}
		}

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException {
			// were we expecting chars?
			if (buf != null) {
				buf.append(new String(ch, start, length));
			}
		}
	}

	private Map<String, String> setParams(String query) {
		Map<String, String> _params = new HashMap<>();
		//String[] t = _query.split("?");
		//String query = t[1];
		if (query != null && query.length() > 1) {
			//String qs = query.substring(1);
			String[] kvPairs = query.split("##"); //$NON-NLS-1$
			for (int i = 0; i < kvPairs.length; i++) {
				String[] kv = kvPairs[i].split("=", 2); //$NON-NLS-1$
				if (kv.length > 1) {
					_params.put(kv[0], kv[1]);
				} else {
					_params.put(kv[0], ""); //$NON-NLS-1$
				}
			}
		}
		return _params;
	}

	private String getParameter(String name) {
		return params.get(name);
	}

	private class ContentThread extends Thread{

		@Override
		public void run()
		{
			threadRunning = true;
			items = Collections.synchronizedList(new ArrayList<>());

			try {
				IntroPlugin.logDebug("Open Connection: "+getParameter("url")); //$NON-NLS-1$ //$NON-NLS-2$
				URL url = new URL(getParameter("url")); //$NON-NLS-1$
				URLConnection conn = url.openConnection();

				// set connection timeout to 6 seconds
				setTimeout(conn, SOCKET_TIMEOUT); // Connection timeout to 6 seconds
				conn.connect();
				try (InputStream in = url.openStream()) {
					SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
					parser.parse(in, new RSSHandler());
					refresh();
				}

			} catch (Exception e) {
				IntroPlugin.logError(
						NLS.bind(
								Messages.RSS_Malformed_feed,
								getParameter("url"))); //$NON-NLS-1$
				refresh();
			} finally {
				threadRunning = false;
			}

		}

		private void setTimeout(URLConnection conn, int milliseconds) {
			Class<? extends URLConnection> conClass = conn.getClass();
			try {
				Method timeoutMethod = conClass.getMethod(
						"setConnectTimeout", new Class[]{ int.class } ); //$NON-NLS-1$
				timeoutMethod.invoke(conn, new Object[] { Integer.valueOf(milliseconds)} );
			} catch (Exception e) {
			     // If running on a 1.4 JRE an exception is expected, fall through
			}
		}
	}

	private class TimeoutThread extends Thread
	{
		@Override
		public void run()
		{
			try{
				Thread.sleep(SOCKET_TIMEOUT);
			}catch(Exception ex){
				IntroPlugin.logError("Timeout failed.", ex); //$NON-NLS-1$
			}
			if (threadRunning)
			{
				threadRunning = false;
				refresh();
			}
		}
	}
}
