/*=============================================================================#
 # Copyright (c) 2010, 2020 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.IMAGES;
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.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

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.runtime.CommonsRuntime;
import org.eclipse.statet.jcommons.runtime.bundle.BundleEntry;
import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec;
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.http.HttpHeaderUtils;
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.RHelpCore;
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 MediaTypeProvider DOC_MEDIA_TYPES;
	static {
		final CustomMediaTypeProvider docMediaTypes= new CustomMediaTypeProvider();
		docMediaTypes.addName("README", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMediaTypes.addName("COPYING", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMediaTypes.addName("LICENSE", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMediaTypes.addName("AUTHORS", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMediaTypes.addName("THANKS", "text/plain;charset=iso-8859-1"); //$NON-NLS-1$ //$NON-NLS-2$
		docMediaTypes.addName("DESCRIPTION", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$
		docMediaTypes.addExt("Rnw", "text/plain"); //$NON-NLS-1$ //$NON-NLS-2$
		DOC_MEDIA_TYPES= docMediaTypes;
	}
	
	@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;
	
	private final Map<String, byte[]> images= new HashMap<>();
	
	
	@SuppressWarnings("null")
	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 ServletMediaTypeProvider(getServletContext()));
		this.fileResourceHandler.setSpecialMediaTypes(DOC_MEDIA_TYPES);
		this.fileResourceHandler.setCacheControl("max-age=600, must-revalidate"); //$NON-NLS-1$
		
		this.serverForwardHandler= serverForwardHandler;
		
		loadImages();
	}
	
	@Override
	public void init(final ServletConfig config) throws ServletException {
		super.init(config);
	}
	
	@Override
	public void destroy() {
		super.destroy();
	}
	
	
	private void loadImages() {
		final List<String> names= ImCollections.newList(
				"rpackage.png", //$NON-NLS-1$
				"rhelp-page.png", "rhelp-page-internal.png", //$NON-NLS-1$ //$NON-NLS-2$
				"rhelp-topic.png", "rhelp-topic-internal.png" ); //$NON-NLS-1$ //$NON-NLS-2$
		try {
			final List<BundleEntry> bundles= CommonsRuntime.getEnvironment().resolveBundles(
					ImCollections.newList(new BundleSpec(RHelpCore.BUNDLE_ID, RHelpCore.class)) );
			ITER_IMAGES: for (final String name : names) {
				final String resourcePathString= "images/" + name; //$NON-NLS-1$
				for (final BundleEntry bundle : bundles) {
					final Path resourcePath= bundle.getResourcePath(resourcePathString);
					if (resourcePath != null && Files.isReadable(resourcePath)) {
						final byte[] bytes= Files.readAllBytes(resourcePath);
						this.images.put(name, bytes);
						continue ITER_IMAGES;
					}
				}
				throw new IOException(String.format("File note found '%1$s'.", resourcePathString));
			}
		}
		catch (final Exception e) {
			log("An error occurred when loading images.", e);
			this.images.clear();
		}
	}
	
	
	@Override
	protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
			throws ServletException, IOException {
		final String path= req.getPathInfo();
		try {
			if (path != null) {
				if (path.startsWith('/' + IMAGES + '/')) {
					processImage(path.substring(IMAGES.length() + 2), req, resp);
					return;
				}
				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(HttpHeaderUtils.LOCATION_NAME, 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; }");
		
		writer.println("img.icon { vertical-align: text-top; padding-top: 1px; padding-right: 2px; margin-right: 2px; }");
		
		customizeCss(writer);
	}
	
	private void processImage(final String imgName,
			final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
		final byte[] content= this.images.get(imgName);
		if (content != null) {
			resp.setContentType("image/png"); //$NON-NLS-1$
			resp.setHeader("Cache-Control", "max-age=600, public"); //$NON-NLS-1$
			final ServletOutputStream out= resp.getOutputStream();
			out.write(content);
			out.close();
			return;
		}
		else {
			resp.sendError(HttpServletResponse.SC_NOT_FOUND);
			return;
		}
	}
	
	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= Path.of(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$
		
		final String basePath= "../../"; //$NON-NLS-1$
		final String baseImagesPath= "../../../" + IMAGES + '/';
		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$
				printIcon(writer, baseImagesPath,
						(page.isInternal()) ? "rhelp-topic-internal.png" : "rhelp-topic.png" ); //$NON-NLS-1$ //$NON-NLS-2$
				writer.write("<a href=\""); //$NON-NLS-1$
				writer.write(basePath);
				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(basePath);
				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 boolean showInternal= getShowInternal();
		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(' ');
			for (; j < packageTopics.size(); j++) {
				final RHelpTopicEntry topic= packageTopics.get(j);
				if (topic.getTopic().length() > 0) {
					final char c= Character.toUpperCase(topic.getTopic().charAt(0));
					if (c >= 'A' && c <= 'Z') {
						if (c > i) {
							break;
						}
						if (c == i && (showInternal || !topic.getPage().isInternal())) {
							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;
						}
					}
				}
			}
			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 baseTopicsPath= LIBRARY_HTML + '/';
		final String baseImagesPath= "../../../" + IMAGES + '/';
		int lastChar= 0;
		for (final RHelpTopicEntry topic : packageTopics) {
			final RHelpPage page= topic.getPage();
			if (showInternal || !page.isInternal()) {
				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(baseTopicsPath);
				writer.write(page.getName());
				writer.write(".html"); //$NON-NLS-1$
				writer.write('"');
				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("\">"); //$NON-NLS-1$
				printIcon(writer, baseImagesPath,
						((page.isInternal()) ? "rhelp-topic-internal.png" : "rhelp-topic.png") ); //$NON-NLS-1$ //$NON-NLS-2$
				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 + '/';
		final String baseImagesPath= basePath + "../../" + IMAGES + '/'; //$NON-NLS-1$
		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 style=\"white-space: nowrap;\">"); //$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(">"); //$NON-NLS-1$
			printIcon(writer, baseImagesPath, "rpackage.png"); //$NON-NLS-1$
			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 printIcon(final PrintWriter writer, final String imageBasePath,
			final String imageName) {
		if (this.images.isEmpty()) {
			return;
		}
		writer.write("<img class=\"icon\" src=\""); //$NON-NLS-1$
		writer.write(imageBasePath);
		writer.write(imageName);
		writer.write("\"/>"); //$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 boolean getShowInternal() {
		return true;
	}
	
	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) {
	}
	
}
