/*=============================================================================#
 # Copyright (c) 2010, 2019 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rhelp.core.http;

import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.CAT_DOC;
import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.CAT_LIBRARY;
import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.LIBRARY_DOC;
import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.LIBRARY_HELP;
import static org.eclipse.statet.internal.rhelp.core.RHelpWebapp.LIBRARY_HTML;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpHeader;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.Status;
import org.eclipse.statet.jcommons.status.StatusException;

import org.eclipse.statet.internal.rhelp.core.REnvHelpImpl;
import org.eclipse.statet.internal.rhelp.core.REnvHelpIndex;
import org.eclipse.statet.internal.rhelp.core.RHelpWebapp;
import org.eclipse.statet.internal.rhelp.core.RHelpWebapp.RequestInfo;
import org.eclipse.statet.internal.rhelp.core.index.RHelpHtmlUtils;
import org.eclipse.statet.internal.rhelp.core.server.ServerClientSupport;
import org.eclipse.statet.rhelp.core.DocResource;
import org.eclipse.statet.rhelp.core.REnvHelp;
import org.eclipse.statet.rhelp.core.REnvHelpConfiguration;
import org.eclipse.statet.rhelp.core.RHelpManager;
import org.eclipse.statet.rhelp.core.RHelpPage;
import org.eclipse.statet.rhelp.core.RHelpTopicEntry;
import org.eclipse.statet.rhelp.core.RPkgHelp;
import org.eclipse.statet.rhelp.core.TopicDocResource;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;
import org.eclipse.statet.rj.renv.core.RLibLocation;
import org.eclipse.statet.rj.renv.core.RPkgDescription;


/**
 * Abstract R help servlet.
 */
@NonNullByDefault
public abstract class RHelpHttpServlet extends HttpServlet {
	
	private static final long serialVersionUID= 1L;
	
	
	private static final String PACKAGE_INDEX_PAGE_NAME= "00Index"; //$NON-NLS-1$
	
	private static final String ATTR_RENV_ID= "rhelp.renv.id"; //$NON-NLS-1$
	private static final String ATTR_RENV_RESOLVED= "rhelp.renv.resolved"; //$NON-NLS-1$
	private static final String ATTR_RENV_HELP= "rhelp.renv.help"; //$NON-NLS-1$
	private static final String ATTR_RENV_CONFIG= "rhelp.renv.config"; //$NON-NLS-1$
	
	
	private static final MimeTypes DOC_MIME_TYPES;
	static {
		final CustomMimeTypes docMimeTypes= new CustomMimeTypes();
		docMimeTypes.addName("README", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMimeTypes.addName("COPYING", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMimeTypes.addName("LICENSE", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMimeTypes.addName("AUTHORS", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMimeTypes.addName("THANKS", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMimeTypes.addName("DESCRIPTION", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$
		docMimeTypes.addExt("Rnw", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$
		DOC_MIME_TYPES= docMimeTypes;
	}
	
	@SuppressWarnings("null")
	private static String getREnvId(final HttpServletRequest req) {
		return (String) req.getAttribute(ATTR_RENV_ID);
	}
	
	@SuppressWarnings("null")
	private static REnv getREnv(final HttpServletRequest req) {
		return (REnv) req.getAttribute(ATTR_RENV_RESOLVED);
	}
	
	@SuppressWarnings("null")
	private static REnvHelpImpl getREnvHelp(final HttpServletRequest req) {
		return (REnvHelpImpl) req.getAttribute(ATTR_RENV_HELP);
	}
	
	@SuppressWarnings("null")
	private static REnvHelpConfiguration getREnvConfig(final HttpServletRequest req) {
		return (REnvHelpConfiguration) req.getAttribute(ATTR_RENV_CONFIG);
	}
	
	private static void printSaveHtml(final Writer writer, final String s) throws IOException {
		final int length= s.length();
		int next= 0;
		for (int i= 0; i < length; ) {
			final char c= s.charAt(i);
			switch (c) {
			case '"':
				if (i > next) {
					writer.write(s, next, i - next);
				}
				writer.write("&quot;"); //$NON-NLS-1$
				next= ++i;
				continue;
			case '&':
				if (i > next) {
					writer.write(s, next, i - next);
				}
				writer.write("&amp;"); //$NON-NLS-1$
				next= ++i;
				continue;
			case '\'':
				if (i > next) {
					writer.write(s, next, i - next);
				}
				// &apos; see http://www.w3.org/TR/xhtml1/#C_16
				writer.write("&#39;"); //$NON-NLS-1$
				next= ++i;
				continue;
			case '<':
				if (i > next) {
					writer.write(s, next, i - next);
				}
				writer.write("&lt;"); //$NON-NLS-1$
				next= ++i;
				continue;
			case '>':
				if (i > next) {
					writer.write(s, next, i - next);
				}
				writer.write("&gt;"); //$NON-NLS-1$
				next= ++i;
				continue;
			default:
				i++;
				continue;
			}
		}
		if (length > next) {
			writer.write(s, next, length - next);
		}
	}
	
	
	private RHelpManager rHelpManager;
	
	private ResourceHandler fileResourceHandler;
	
	private @Nullable HttpForwardHandler serverForwardHandler;
	
	
	public RHelpHttpServlet() {
	}
	
	
	protected void init(final RHelpManager rHelpManager,
			final @Nullable ResourceHandler fileResourceHandler,
			final @Nullable HttpForwardHandler serverForwardHandler) {
		this.rHelpManager= rHelpManager;
		
		this.fileResourceHandler= (fileResourceHandler != null) ? fileResourceHandler :
				new SimpleResourceHandler(new ServletMimeTypes(getServletContext()));
		this.fileResourceHandler.setSpecialMimeTypes(DOC_MIME_TYPES);
		this.fileResourceHandler.setCacheControl("max-age=600, must-revalidate"); //$NON-NLS-1$
		
		this.serverForwardHandler= serverForwardHandler;
	}
	
	@Override
	public void init(final ServletConfig config) throws ServletException {
		super.init(config);
	}
	
	@Override
	public void destroy() {
		super.destroy();
	}
	
	
	@Override
	protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
			throws ServletException, IOException {
		final String path= req.getPathInfo();
		try {
			if (path != null) {
				if (path.endsWith("/R.css")) { //$NON-NLS-1$
					processCss(req, resp);
					return;
				}
				final RequestInfo info= RHelpWebapp.extractRequestInfo(path);
				if (info != null) {
					if (!checkREnv(info.rEnvId, req, resp)) {
						return;
					}
					if (info.cat == null) {
						printEnvIndex(req, resp);
						return;
					}
					else if (info.cat == RHelpWebapp.CAT_LIBRARY) {
						switch (info.cmd) {
						case RHelpWebapp.PKGCMD_IDX:
							processPkgIndex(info.pkgName, req, resp);
							return;
						case RHelpWebapp.PKGCMD_HTML_PAGE:
							processHelpPage(info.pkgName, info.detail, req, resp);
							return;
						case RHelpWebapp.PKGCMD_HTML_RESOURCE:
							processPkgRes(info.pkgName, LIBRARY_HELP, info.detail, req, resp);
							return;
						case RHelpWebapp.PKGCMD_TOPIC:
							processTopic(info.pkgName, info.detail, req, resp);
							return;
						case RHelpWebapp.PKGCMD_DOC_IDX:
							processPkgRes(info.pkgName, LIBRARY_DOC, "index.html", req, resp); //$NON-NLS-1$
							return;
						case RHelpWebapp.PKGCMD_DOC_RES:
							processPkgRes(info.pkgName, LIBRARY_DOC, info.detail, req, resp);
							return;
						case RHelpWebapp.PKGCMD_DESCRIPTION_RES:
							processPkgRes(info.pkgName, null, "DESCRIPTION", req, resp); //$NON-NLS-1$
							return;
						}
					}
					else if (info.cat == RHelpWebapp.CAT_DOC) {
						processEnvDoc(info.detail, req, resp);
						return;
					}
				}
			}
			resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
			return;
		}
		catch (final StatusException e) {
			final Status status= e.getStatus();
			final int httpStatus;
			switch (status.getCode()) {
			case REnvHelpIndex.TIMEOUT_ERROR:
			case REnvHelpIndex.CONNECT_ERROR:
				httpStatus= HttpServletResponse.SC_GATEWAY_TIMEOUT;
				break;
			default:
				httpStatus= HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
				break;
			}
			resp.sendError(httpStatus, status.getMessage());
			return;
		}
		finally {
			final REnvHelp help= (REnvHelp) req.getAttribute(ATTR_RENV_HELP);
			if (help != null) {
				help.unlock();
			}
		}
	}
	
	protected StringBuilder getServletPath(final HttpServletRequest req) {
		return new StringBuilder()
				.append(req.getContextPath())
				.append(req.getServletPath());
	}
	
	protected void sendPathRedirect(final String path,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
//		resp.sendRedirect(path.toString()); // converts relativ path to absolute
		
		resp.resetBuffer();
		resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
		resp.setHeader(HttpHeader.LOCATION.asString(), path);
	}
	
	
	private boolean checkREnv(final String id,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		REnv rEnv= this.rHelpManager.getREnv(id);
		if (rEnv != null) {
			rEnv= rEnv.resolve();
		}
		final REnvHelpConfiguration config;
		if (rEnv != null && (config= rEnv.get(REnvHelpConfiguration.class)) != null) {
			req.setAttribute(ATTR_RENV_ID, id);
			req.setAttribute(ATTR_RENV_RESOLVED, rEnv);
			final REnvHelp help= this.rHelpManager.getHelp(rEnv);
			if (help != null) {
				req.setAttribute(ATTR_RENV_HELP, help);
				req.setAttribute(ATTR_RENV_CONFIG, config);
				return true;
			}
			resp.sendError(HttpServletResponse.SC_NOT_FOUND,
					"The R library of the requested R environment <code>" + rEnv.getName() + "</code> " +
					"is not yet indexed. Please run the indexer first to enable R help support.");
			return false;
		}
		else {
			final String message= (id.startsWith("default-")) ? //$NON-NLS-1$
					"The requested default R environment is missing. " +
							"Please configure an environment as default." :
					"The requested R environment doesn't exist. " +
							"Please change the environment.";
			resp.sendError(HttpServletResponse.SC_NOT_FOUND, message);
			return false;
		}
	}
	
	private void processHelpPage(final String pkgName, final String detail,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException,
					StatusException {
		if (detail != null && detail.equalsIgnoreCase(PACKAGE_INDEX_PAGE_NAME)) {
			sendPathRedirect(getServletPath(req)
					.append('/').append(getREnvId(req))
					.append('/' + CAT_LIBRARY +
							'/').append(pkgName).append('/')
					.toString(), req, resp );
			return;
		}
		
		final REnvHelpImpl help= getREnvHelp(req);
		final RPkgHelp pkgHelp= help.getPkgHelp(pkgName);
		if (pkgHelp != null) {
			final String qs= req.getParameter(RHelpWebapp.PAR_QUERY_STRING);
			String html= help.getHtmlPage(pkgHelp, detail, qs);
			if (html != null) {
				if (qs != null) {
					html= RHelpHtmlUtils.formatHtmlMatches(html);
				}
				printHtmlPage(html, req, resp);
				return;
			}
			final RHelpPage page= pkgHelp.getPageForTopic(detail);
			if (page != null) {
				redirect(page, req, resp);
				return;
			}
		}
		resp.sendError(HttpServletResponse.SC_NOT_FOUND,
				"Help page <code>" + detail + "</code> {<code>" + pkgName + "</code>} not found.");
		return;
	}
	
	private void processPkgRes(final String pkgName, final @Nullable String resSub, final String path,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException, ServletException {
		final REnvHelpImpl help= getREnvHelp(req);
		final REnvHelpConfiguration rEnvConfig= getREnvConfig(req);
		
		Path libDirectory= null;
		if (rEnvConfig.isLocal()) {
			final RPkgHelp pkgHelp= help.getPkgHelp(pkgName);
			if (pkgHelp != null) {
				final RPkgDescription pkgDescription= pkgHelp.getPkgDescription();
				final RLibLocation libLocation= pkgDescription.getLibLocation();
				libDirectory= libLocation.getDirectoryPath();
			}
		}
		else {
			switch (rEnvConfig.getStateSharedType()) {
			case REnvConfiguration.SHARED_SERVER:
				forwardToServer(rEnvConfig, req, resp);
				return;
			case REnvConfiguration.SHARED_DIRECTORY:
				// TODO
				break;
			default:
				resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				return;
			}
		}
		if (libDirectory == null) {
			resp.sendError(HttpServletResponse.SC_NOT_FOUND);
			return;
		}
		Path directory= libDirectory.resolve(pkgName);
		if (resSub != null) {
			directory= directory.resolve(resSub);
		}
		
		serveFileResource(directory, path, null, req, resp);
	}
	
	private void processPkgIndex(final String pkgName,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException,
					StatusException {
		final REnvHelpImpl help= getREnvHelp(req);
		final RPkgHelp pkgHelp= help.getPkgHelp(pkgName);
		if (pkgHelp != null) {
			final ImList<RHelpTopicEntry> topics= pkgHelp.getTopics();
			if (topics != null) {
				printPackageIndex(pkgHelp, topics, req, resp);
				return;
			}
		}
		resp.sendError(HttpServletResponse.SC_NOT_FOUND,
				"Help for package <code>" + pkgName + "</code> not found.");
		return;
	}
	
	private void processTopic(final String pkgName, final String detail,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException,
					StatusException {
		final REnvHelp help= getREnvHelp(req);
		final RPkgHelp pkgHelp= help.getPkgHelp(pkgName);
		if (pkgHelp != null) {
			final RHelpPage page= pkgHelp.getPageForTopic(detail);
			if (page != null) {
				redirect(page, req, resp);
				return;
			}
		}
		final List<RHelpPage> pages= help.getPagesForTopic(detail, null);
		if (pages.size() == 1) {
			redirect(pages.get(0), req, resp);
			return;
		}
		else {
			printTopicList(detail, pages, req, resp);
			return;
		}
	}
	
	private void processCss(
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		final PrintWriter writer= createCssDoc(req, resp);
		
		writer.println("span.acronym { font-size: small }\n" + //$NON-NLS-1$
				"span.env { font-family: monospace }\n" + //$NON-NLS-1$
				"span.file { font-family: monospace }\n" + //$NON-NLS-1$
				"span.option { font-family: monospace }\n" + //$NON-NLS-1$
				"span.pkg { font-weight: bold }\n" + //$NON-NLS-1$
				"span.samp { font-family: monospace }"); //$NON-NLS-1$
		
		writer.println("body { line-height: 125%; margin: 1em; padding: 0; color: black; }"); //$NON-NLS-1$
		writer.println("table { margin: 0.4em 0 0.4em 0; border-collapse:collapse; border:0px; font-size: 100% }"); //$NON-NLS-1$
		writer.println("td { padding: 0.2em 0.8em 0.2em 0; border:0px; }"); //$NON-NLS-1$
		writer.println("h2 { font-size: 120%; font-weight: bold; margin: 0 0 0.6em 0; }"); //$NON-NLS-1$
		writer.println("h3 { font-size: 110%; font-weight: bold; letter-spacing: 0.05em; margin: 1.0em 0 0.6em 0; }"); //$NON-NLS-1$
		writer.println("p, pre { margin: 0.6em 0 0.6em 0; }"); //$NON-NLS-1$
		writer.println("td { vertical-align: top; }"); //$NON-NLS-1$
		writer.println("hr { margin-top: 0.8em; clear: both; }"); //$NON-NLS-1$
		
		writer.println("div.toc { display: none; font-size: 80%; line-height: 125%; padding: 0.2em 0.8em 0.4em; }"); //$NON-NLS-1$
		writer.println("div.toc ul { list-style: none; padding: 0; margin: 0 }"); //$NON-NLS-1$
		writer.println("div.toc pre { margin: 0 0 0.4em; }"); //$NON-NLS-1$
		writer.println("div.toc a { text-decoration: none; color: black; }"); //$NON-NLS-1$
		writer.println("div.toc a:visited { text-decoration: none; color: black; }"); //$NON-NLS-1$
		
		writer.println("a.action { text-decoration: none; }");
		writer.println("a.action small { padding-left: 1px; padding-right: 1px; }");
		writer.println("a.action:hover small { background-color: lightgrey; color: black; }");
		
		customizeCss(writer);
	}
	
	private void processEnvDoc(final String path,
			final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		final REnvHelpImpl help= getREnvHelp(req);
		final REnvHelpConfiguration rEnvConfig= getREnvConfig(req);
		
		Path directory= null;
		if (rEnvConfig.isLocal()) {
			final String docDir= help.getDocDir();
			if (docDir != null) {
				directory= Paths.get(docDir);
			}
		}
		else {
			switch (rEnvConfig.getStateSharedType()) {
			case REnvConfiguration.SHARED_SERVER:
				forwardToServer(rEnvConfig, req, resp);
				return;
			case REnvConfiguration.SHARED_DIRECTORY:
				// TODO
				break;
			default:
				resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				return;
			}
		}
		if (directory == null) {
			resp.sendError(HttpServletResponse.SC_NOT_FOUND, "R doc directory not found.");
			return;
		}
		
		serveFileResource(directory, path, req.getParameter(RHelpWebapp.PAR_ACTION), req, resp);
	}
	
	private PrintWriter createHtmlDoc(final String title,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		resp.setContentType("text/html;charset=UTF-8"); //$NON-NLS-1$
		resp.setHeader("Cache-Control", "max-age=30, must-revalidate"); //$NON-NLS-1$ //$NON-NLS-2$
		final PrintWriter writer= resp.getWriter();
		writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); //$NON-NLS-1$
		writer.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"); //$NON-NLS-1$
		
		writer.println("<html><head>"); //$NON-NLS-1$
		writer.write("<title>"); //$NON-NLS-1$
		printSaveHtml(writer, title);
		writer.write("</title>"); //$NON-NLS-1$
		writer.write("<link rel=\"stylesheet\" type=\"text/css\" href=\""); //$NON-NLS-1$
		writer.write(getServletPath(req)
				.append("/R.css")
				.toString() );
		writer.println("\"/>"); //$NON-NLS-1$
		return writer;
	}
	
	private void redirect(final RHelpPage page,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		sendPathRedirect(getServletPath(req)
				.append('/').append(getREnvId(req))
				.append('/' + CAT_LIBRARY +
						'/').append(page.getPackage().getName())
				.append('/' + LIBRARY_HTML +
						'/').append(page.getName()).append(".html") //$NON-NLS-1$
				.toString(), req, resp );
	}
	
	private PrintWriter createCssDoc(
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		resp.setContentType("text/css;charset=UTF-8"); //$NON-NLS-1$
		final PrintWriter writer= resp.getWriter();
		writer.println("@charset \"UTF-8\";"); //$NON-NLS-1$
		return writer;
	}
	
	private void printHtmlPage(final String html,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		resp.setContentType("text/html;charset=UTF-8"); //$NON-NLS-1$
		resp.setHeader("Cache-Control", "max-age=30, must-revalidate"); //$NON-NLS-1$ //$NON-NLS-2$
		final PrintWriter writer= resp.getWriter();
		final int idxHead= html.indexOf("</head>"); //$NON-NLS-1$
		if (idxHead > 0) {
			writer.write(html, 0, idxHead);
			customizePageHtmlHeader(req, writer);
			int idxEndExamples= html.lastIndexOf(RHelpWebapp.HTML_END_EXAMPLES);
			if (idxEndExamples > 0) {
				final int idxBeginExamples= html.lastIndexOf(RHelpWebapp.HTML_BEGIN_EXAMPLES, idxEndExamples);
				writer.write(html, idxHead, idxBeginExamples - idxHead);
				customizeExamples(writer, html.substring(
						idxBeginExamples + RHelpWebapp.HTML_BEGIN_EXAMPLES.length(), idxEndExamples));
				idxEndExamples+= RHelpWebapp.HTML_END_EXAMPLES.length();
				writer.write(html, idxEndExamples, html.length() - idxEndExamples);
			}
			else {
				writer.write(html, idxHead, html.length() - idxHead);
			}
		}
		else {
			writer.write(html);
		}
	}
	
	private void printTopicList(final String topic, final List<RHelpPage> pages,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		final PrintWriter writer= createHtmlDoc(String.format("Help on topic '%1$s'", topic),
				req, resp );
		final String codeTopic= "<code>" + topic + "</code>"; //$NON-NLS-1$ //$NON-NLS-2$
		customizeIndexHtmlHeader(req, writer);
		writer.println("</head><body>"); //$NON-NLS-1$
		writer.write("<h2>"); //$NON-NLS-1$
		writer.write(String.format("Help on topic %1$s", codeTopic));
		writer.write("</h2>"); //$NON-NLS-1$
		
		if (pages != null && !pages.isEmpty()) {
			writer.write("<p>"); //$NON-NLS-1$
			writer.write(String.format("Help on topic %1$s was found in the following pages:", codeTopic));
			writer.println("</p>"); //$NON-NLS-1$
			
			Collections.sort(pages);
			writer.write("<table>"); //$NON-NLS-1$
			for (final RHelpPage page : pages) {
				writer.write("<tr><td style=\"white-space: nowrap;\">"); //$NON-NLS-1$
				writer.write("<a href=\"" + "../../"); //$NON-NLS-1$
				writer.write(page.getPackage().getName());
				writer.write('/' + LIBRARY_HTML + '/');
				writer.write(page.getName());
				writer.write(".html" + "\"><code>"); //$NON-NLS-1$
				writer.write(page.getName());
				writer.write("</code></a> {"); //$NON-NLS-1$
				writer.write("<a href=\"../../"); //$NON-NLS-1$
				writer.write(page.getPackage().getName());
				writer.write("/" + "\" title=\""); //$NON-NLS-1$
				writer.write(page.getPackage().getName());
				writer.write(" ["); //$NON-NLS-1$
				writer.write(page.getPackage().getVersion().toString());
				writer.write("]\n"); //$NON-NLS-1$
				printSaveHtml(writer, page.getPackage().getTitle());
				writer.write("\"><code>"); //$NON-NLS-1$
				writer.write(page.getPackage().getName());
				writer.write("</code></a>}</td>"); //$NON-NLS-1$
				writer.write("<td>"); //$NON-NLS-1$
				printSaveHtml(writer, page.getTitle());
				writer.write("</td></tr>"); //$NON-NLS-1$
			}
			writer.write("</table>"); //$NON-NLS-1$
		}
		else {
			writer.write(String.format("No help found on topic %1$s in any package in the R library.", codeTopic));
		}
		writer.println("</body></html>"); //$NON-NLS-1$
	}
	
	private void printPackageIndex(final RPkgHelp pkgHelp, final List<RHelpTopicEntry> packageTopics,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		final RPkgDescription pkgDescription= pkgHelp.getPkgDescription();
		final List<TopicDocResource> vignettes= ImCollections.emptyList();
		final PrintWriter writer= createHtmlDoc(String.format("Package '%1$s' - %2$s", pkgHelp.getName(), pkgHelp.getTitle()), req,
				resp );
		customizeIndexHtmlHeader(req, writer);
		writer.println("</head><body>"); //$NON-NLS-1$
		writer.write("<table class=\"header\"><tr><td>"); //$NON-NLS-1$
		writer.write(pkgHelp.getName());
		writer.write(" ["); //$NON-NLS-1$
		writer.write(pkgHelp.getVersion().toString());
		writer.write("]"); //$NON-NLS-1$
		writer.println("</td></tr></table>"); //$NON-NLS-1$
		
		writer.println("<div class=\"toc\"><ul>"); //$NON-NLS-1$
//		writer.println("<li><a href=\"#description\">Description</a></li>");
		writer.write("<li><a href=\"#topics\">Help Topics</a><pre>"); //$NON-NLS-1$
		TOC: for (int i= 'A', j= 0; i <= 'Z'; i++) {
			if ((i - 'A') % 7 == 0) {
				writer.println();
			}
			writer.print(' ');
			String name;
			while (j < packageTopics.size() &&
					(name= packageTopics.get(j).getTopic()) != null && name.length() > 0) {
				final char c= Character.toUpperCase(name.charAt(0));
				if (c >= 'A' && c <= 'Z') {
					if (c > i) {
						break;
					}
					if (c == i) {
						writer.write("<a href=\"#idx"); //$NON-NLS-1$
						writer.print((char) (32 + c)); // lowercase
						writer.write("\" class=\"mnemonic\">"); //$NON-NLS-1$
						writer.print(c);
						writer.write("</a>"); //$NON-NLS-1$
						continue TOC;
					}
				}
				j++;
			}
			writer.print((char) i);
		}
		writer.println("</pre></li>"); //$NON-NLS-1$
		if (!vignettes.isEmpty()) {
			writer.println("<li><a href=\"#vignettes\">Other Documentation</a></li>"); //$NON-NLS-1$
		}
		writer.println("<li><a href=\"#about\">About</a></li>"); //$NON-NLS-1$
		writer.println("</ul></div>"); //$NON-NLS-1$
		
		writer.write("<h2>"); //$NON-NLS-1$
		printSaveHtml(writer, pkgHelp.getTitle());
		writer.write("</h2>"); //$NON-NLS-1$
		
		if (pkgDescription != null) {
			final String description= pkgDescription.getDescription();
			if (description.length() > 0) {
				writer.write("<h3 id=\"description\">Description</h3>"); //$NON-NLS-1$
				writer.write("<p>"); //$NON-NLS-1$
				printSaveHtml(writer, description);
				if (description.charAt(description.length() - 1) != '.') {
					writer.print('.');
				}
				writer.write("</p>"); //$NON-NLS-1$
			}
		}
		
		writer.write("<h3 id=\"topics\">Help Topics</h3>"); //$NON-NLS-1$
		writer.write("<table>"); //$NON-NLS-1$
		final String basePath= LIBRARY_HTML + '/';
		int lastChar= 0;
		for (final RHelpTopicEntry topic : packageTopics) {
			final RHelpPage page= topic.getPage();
			final String alias= topic.getTopic();
			writer.write("<tr><td style=\"white-space: nowrap;\">"); //$NON-NLS-1$
			writer.write("<a href=\""); //$NON-NLS-1$
			writer.write(basePath);
			writer.write(page.getName());
			writer.write(".html"); //$NON-NLS-1$
			writer.print('"');
			if (alias.length() > 0) {
				final char c= Character.toUpperCase(alias.charAt(0));
				if (c >= 'A' && c <= 'Z' && c > lastChar) {
					lastChar= c;
					writer.write(" id=\"idx"); //$NON-NLS-1$
					writer.print((char) (32 + c)); // lowercase
					writer.print('"');
				}
			}
			writer.write(" title=\""); //$NON-NLS-1$
			writer.write(page.getName());
			writer.write(" {"); //$NON-NLS-1$
			writer.write(pkgHelp.getName());
			writer.write("}\n"); //$NON-NLS-1$
			printSaveHtml(writer, page.getTitle());
			writer.write("\"><code>"); //$NON-NLS-1$
			writer.write(alias);
			writer.write("</code></a>"); //$NON-NLS-1$
			writer.write("</td><td>"); //$NON-NLS-1$
			printSaveHtml(writer, page.getTitle());
			writer.write("</td></tr>"); //$NON-NLS-1$
		}
		writer.write("</table>"); //$NON-NLS-1$
		
		if (!vignettes.isEmpty()) {
			writer.write("<h3 id=\"vignettes\">Vignettes and Other Documentation</h3>"); //$NON-NLS-1$
		}
		
		writer.write("<h3 id=\"about\">About</h3>"); //$NON-NLS-1$
		if (pkgDescription != null) {
			writer.write("<table>");
			if (pkgDescription.getAuthor() != null && pkgDescription.getAuthor().length() > 0) {
				writer.write("<tr><td>Author(s):</td>");
				writer.write("<td>"); //$NON-NLS-1$
				printSaveHtml(writer, pkgDescription.getAuthor());
				writer.write("</td>"); //$NON-NLS-1$
			}
			if (pkgDescription.getMaintainer() != null && pkgDescription.getMaintainer().length() > 0) {
				writer.write("<tr><td>Maintainer:</td>"); //$NON-NLS-1$
				writer.write("<td>"); //$NON-NLS-1$
				printSaveHtml(writer, pkgDescription.getMaintainer());
				writer.write("</td>"); //$NON-NLS-1$
			}
			if (pkgDescription.getUrl() != null && pkgDescription.getUrl().length() > 0) {
				writer.write("<tr><td>URL:</td>"); //$NON-NLS-1$
				writer.write("<td><a href=\""); //$NON-NLS-1$
				printSaveHtml(writer, pkgDescription.getUrl());
				writer.write("\"><code>"); //$NON-NLS-1$
				printSaveHtml(writer, pkgDescription.getUrl());
				writer.write("</code></a></td>"); //$NON-NLS-1$
			}
			writer.write("</table>");
		}
		writer.write("<p><a href=\"description\">DESCRIPTION file</a></p>"); //$NON-NLS-1$
		
		writer.println("</body></html>"); //$NON-NLS-1$
	}
	
	private void printEnvIndex(
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		final REnvHelpImpl help= getREnvHelp(req);
		final REnvHelpConfiguration rEnvConfig= getREnvConfig(req);
		final REnv rEnv= help.getREnv();
		final List<RPkgHelp> packages= help.getPkgs();
		final PrintWriter writer= createHtmlDoc(String.format("R Environment '%1$s'", rEnv.getName()), req,
				resp );
		final String basePath= getServletPath(req)
				.append('/').append(rEnv.getId())
				.toString();
		final String baseLibPath= basePath + '/' + CAT_LIBRARY + '/';
		final String baseDocPath= basePath + '/' + CAT_DOC + '/';
		customizeIndexHtmlHeader(req, writer);
		writer.println("</head><body>"); //$NON-NLS-1$
		
		// toc
		writer.println("<div class=\"toc\"><ul>"); //$NON-NLS-1$
		writer.write("<li><a href=\"#manuals\">Manuals</a></li>"); //$NON-NLS-1$
		writer.write("<li><a href=\"#packages\">Packages</a><pre>"); //$NON-NLS-1$
		TOC: for (int i= 'A', j= 0; i <= 'Z'; i++) {
			if ((i - 'A') % 7 == 0) {
				writer.println();
			}
			writer.print(' ');
			String name;
			while (j < packages.size() &&
					(name= packages.get(j).getName()) != null && name.length() > 0) {
				final char c= Character.toUpperCase(name.charAt(0));
				if (c >= 'A' && c <= 'Z') {
					if (c > i) {
						break;
					}
					if (c == i) {
						writer.write("<a href=\"#idx"); //$NON-NLS-1$
						writer.print((char) (32 + c)); // lowercase
						writer.write("\" class=\"mnemonic\">"); //$NON-NLS-1$
						writer.print(c);
						writer.write("</a>"); //$NON-NLS-1$
						continue TOC;
					}
				}
				j++;
			}
			writer.print((char) i);
		}
		writer.println("</pre></li>"); //$NON-NLS-1$
		if (!help.getMiscResources().isEmpty()) {
			writer.write("<li><a href=\"#misc\">Misc. Material</a></li>"); //$NON-NLS-1$
		}
		writer.println("</ul></div>"); //$NON-NLS-1$
		
		writer.write("<h2>"); //$NON-NLS-1$
		writer.write(rEnv.getName());
		writer.write("</h2>"); //$NON-NLS-1$
		
		writer.write("<h3 id=\"manuals\">Manuals</h3>"); //$NON-NLS-1$
		if (!help.getManuals().isEmpty()) {
			printDocTable(writer, help.getManuals(), baseDocPath, rEnvConfig.isLocal());
		}
		else {
			writer.write("<p>No manuals available for this R installation.</p>");
		}
		
		writer.write("<h3 id=\"packages\">Packages</h3>"); //$NON-NLS-1$
		writer.write("<table>"); //$NON-NLS-1$
		char lastChar= 0;
		for (final RPkgHelp pkgHelp : packages) {
			final String name= pkgHelp.getName();
			writer.write("<tr><td>"); //$NON-NLS-1$
			writer.write("<a href=\""); //$NON-NLS-1$
			writer.write(baseLibPath);
			writer.write(name);
			writer.write("/" + "\" title=\""); //$NON-NLS-1$
			writer.write(name);
			writer.write(" ["); //$NON-NLS-1$
			printSaveHtml(writer, pkgHelp.getVersion().toString());
			writer.print(']');
			writer.print('"');
			if (name.length() > 0) {
				final char c= Character.toUpperCase(name.charAt(0));
				if (c >= 'A' && c <= 'Z' && c > lastChar) {
					lastChar= c;
					writer.write(" id=\"idx"); //$NON-NLS-1$
					writer.print((char) (32 + c)); // lowercase
					writer.print('"');
				}
			}
			writer.write("><code>"); //$NON-NLS-1$
			writer.write(pkgHelp.getName());
			writer.write("</code></a>"); //$NON-NLS-1$
			writer.write("</td><td>"); //$NON-NLS-1$
			printSaveHtml(writer, pkgHelp.getTitle());
			writer.write("</td></tr>"); //$NON-NLS-1$
		}
		writer.write("</table>"); //$NON-NLS-1$
		
		if (!help.getMiscResources().isEmpty()) {
			writer.write("<h3 id=\"misc\">Miscellaneous Material</h3>"); //$NON-NLS-1$
			printDocTable(writer, help.getMiscResources(), baseDocPath, rEnvConfig.isLocal());
		}
		
		writer.write("<hr/>"); //$NON-NLS-1$
		
		writer.println("</body></html>"); //$NON-NLS-1$
	}
	
	
	private void printDocTable(final PrintWriter writer, final List<DocResource> docs,
			final String baseUrl, final boolean local) {
		writer.write("<table>"); //$NON-NLS-1$
		for (final DocResource doc : docs) {
			writer.write("<tr><td>"); //$NON-NLS-1$
			writer.write("<a href=\""); //$NON-NLS-1$
			writer.write(baseUrl);
			writer.write(doc.getPath());
			writer.write("\">"); //$NON-NLS-1$
			writer.write(doc.getTitle());
			writer.write("</a>"); //$NON-NLS-1$
			if (doc.getPdfPath() != null) {
				writer.write("&emsp;[&#8239;<a"); //$NON-NLS-1$
				writer.write(" href=\""); //$NON-NLS-1$
				writer.write(baseUrl);
				writer.write(doc.getPdfPath());
				writer.write("\">PDF</a>");
				if (local && canOpenFile("pdf")) { //$NON-NLS-1$
					writer.write("&#8239;<a class=\"action\""); //$NON-NLS-1$
					writer.write(" href=\""); //$NON-NLS-1$
					writer.write(baseUrl);
					writer.write(doc.getPdfPath());
					writer.write("?action=open");
					writer.write("\" title=\"Open PDF with Eclipse\"><small>(open)</small></a>");
				}
				writer.write("&#8239;]"); //$NON-NLS-1$
			}
			writer.write("</td></tr>"); //$NON-NLS-1$
		}
		writer.write("</table>"); //$NON-NLS-1$
	}
	
	
	private void customizeExamples(final PrintWriter writer, final String html) {
		int idx= 0;
		while (idx < html.length()) {
			int begin= html.indexOf("<pre", idx); //$NON-NLS-1$
			if (begin >= 0) {
				begin= html.indexOf('>', begin + 4);
				if (begin >= 0) {
					begin ++;
					final int end= html.indexOf("</pre", begin); //$NON-NLS-1$
					if (end >= 0) {
						writer.write(html, idx, begin - idx);
						printRCode(writer, html.substring(begin, end));
						idx= end;
						continue;
					}
				}
			}
			break;
		}
		writer.write(html, idx, html.length() - idx);
	}
	
	protected void customizeCss(final PrintWriter writer) {
	}
	
	protected void customizePageHtmlHeader(final HttpServletRequest req, final PrintWriter writer) {
	}
	
	protected void customizeIndexHtmlHeader(final HttpServletRequest req, final PrintWriter writer) {
	}
	
	protected void printRCode(final PrintWriter writer, final String html) {
		writer.write(html);
	}
	
	
	private @Nullable Path checkPath(final Path directory, final String path) {
		try {
			final Path file= directory.resolve(path).toRealPath(LinkOption.NOFOLLOW_LINKS);
			if (file.getNameCount() >= directory.getNameCount() && file.startsWith(directory)) {
				return file;
			}
		}
		catch (final Exception e) {}
		return null;
	}
	
	private void serveFileResource(final Path directory, final String path,
			final @Nullable String action,
			final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		final Path file= checkPath(directory, path);
		if (file == null) {
			resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
			return;
		}
		if (!Files.isRegularFile(file)) {
			resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
			return;
		}
		
		if (action != null && action.equals(RHelpWebapp.ACTION_OPEN)) {
			doOpenFile(file);
			resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
			return;
		}
		
		this.fileResourceHandler.doGet(file, req, resp);
	}
	
	private void forwardToServer(final REnvHelpConfiguration rEnvConfig,
			final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		if (this.serverForwardHandler == null) {
			resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
			return;
		}
		try {
			final ServerClientSupport serverSupport= ServerClientSupport.getInstance();
			final String localId= getREnvId(req);
			final URI serverUrl= serverSupport.toServerBrowseUrl(rEnvConfig,
					req.getPathInfo().substring(localId.length() + 1) );
			this.serverForwardHandler.forward(serverUrl, req, resp);
		}
		catch (final StatusException | URISyntaxException e) {
			throw new ServletException(e);
		}
	}
	
	protected boolean canOpenFile(final String ext) {
		return false;
	}
	
	protected void doOpenFile(final Path file) {
	}
	
}
