/*******************************************************************************
 * Copyright (c) 2000, 2004 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.help.internal.webapp.servlet;

import java.io.*;
import java.net.*;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.eclipse.help.internal.base.*;
import org.eclipse.help.internal.protocols.*;
import org.eclipse.help.internal.webapp.data.*;

/**
 * Performs transfer of data from eclipse to a jsp/servlet
 */
public class EclipseConnector {
	private ServletContext context;
	private static final String errorPageBegin = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" //$NON-NLS-1$
			+ "<html><head>\n" //$NON-NLS-1$
			+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n" //$NON-NLS-1$
			+ "</head>\n" //$NON-NLS-1$
			+ "<body><p>\n"; //$NON-NLS-1$
	private static final String errorPageEnd = "</p></body></html>"; //$NON-NLS-1$
	private static final IFilter filters[] = new IFilter[]{
			new HighlightFilter(), new FramesetFilter()};

	/**
	 * Constructor.
	 */
	public EclipseConnector(ServletContext context) {
		this.context = context;
	}

	public void transfer(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {

		try {

			String url = getURL(req);
			if (url == null)
				return;
			if (url.toLowerCase(Locale.ENGLISH).startsWith("file:/") //$NON-NLS-1$
					|| url.toLowerCase(Locale.ENGLISH).startsWith("jar:file:/")) { //$NON-NLS-1$
				int i = url.indexOf('?');
				if (i != -1)
					url = url.substring(0, i);
				// ensure the file is only accessed from a local installation
				if (BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER
						|| !UrlUtil.isLocalRequest(req)) {
					return;
				}
			} else {
				// enable activities matching url
				// HelpBasePlugin.getActivitySupport().enableActivities(url);

				url = "help:" + url; //$NON-NLS-1$
			}

			URLConnection con = openConnection(url, req, resp);
			resp.setContentType(con.getContentType());

			long maxAge = 0;
			try {
				// getExpiration() throws NullPointerException when URL is
				// jar:file:...
				long expiration = con.getExpiration();
				maxAge = (expiration - System.currentTimeMillis()) / 1000;
				if (maxAge < 0)
					maxAge = 0;
			} catch (Exception e) {
			}
			resp.setHeader("Cache-Control", "max-age=" + maxAge); //$NON-NLS-1$ //$NON-NLS-2$

			InputStream is;
			try {
				is = con.getInputStream();
			} catch (IOException ioe) {
				if (url.toLowerCase(Locale.ENGLISH).endsWith("htm") //$NON-NLS-1$
						|| url.toLowerCase(Locale.ENGLISH).endsWith("html")) { //$NON-NLS-1$
					String error = errorPageBegin
							+ ServletResources.getString("noTopic", req) //$NON-NLS-1$
							+ errorPageEnd;
					is = new ByteArrayInputStream(error.getBytes("UTF8")); //$NON-NLS-1$
				} else {
					return;
				}
			}

			OutputStream out = resp.getOutputStream();
			for (int i = 0; i < filters.length; i++) {
				out = filters[i].filter(req, out);
			}

			transferContent(is, out);
			out.flush();
			is.close();

		} catch (Exception e) {
			//e.printStackTrace();
		}
	}

	/**
	 * Write the body to the response
	 */
	private void transferContent(InputStream inputStream, OutputStream out)
			throws IOException {
		try {
			// Prepare the input stream for reading
			BufferedInputStream dataStream = new BufferedInputStream(
					inputStream);

			// Create a fixed sized buffer for reading.
			// We could create one with the size of availabe data...
			byte[] buffer = new byte[4096];
			int len = 0;
			while (true) {
				len = dataStream.read(buffer); // Read file into the byte array
				if (len == -1)
					break;
				out.write(buffer, 0, len);
			}
		} catch (Exception e) {
			// e.printStackTrace();
		}
	}

	/**
	 * Gets content from the named url (this could be and eclipse defined url)
	 */
	private URLConnection openConnection(String url,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		//System.out.println("help content for: " + url);

		URLConnection con = null;
		if (BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER) {
			// it is an infocentre, add client locale to url
			String locale = UrlUtil.getLocale(request, response);
			if (url.indexOf('?') >= 0) {
				url = url + "&lang=" + locale; //$NON-NLS-1$
			} else {
				url = url + "?lang=" + locale; //$NON-NLS-1$
			}
		}
		// URL helpURL = new URL(url);
		URL helpURL;
		if (url.startsWith("help:")) { //$NON-NLS-1$
			helpURL = new URL("help", //$NON-NLS-1$
					null, -1, url.substring("help:".length()), //$NON-NLS-1$
					HelpURLStreamHandler.getDefault());
		} else {
			helpURL = new URL(url);
		}
		String protocol = helpURL.getProtocol();
		if (!("help".equals(protocol) //$NON-NLS-1$
				|| "file".equals(protocol) //$NON-NLS-1$
		|| "jar".equals(protocol))) { //$NON-NLS-1$
			throw new IOException();
		}
		con = helpURL.openConnection();

		con.setAllowUserInteraction(false);
		con.setDoInput(true);
		con.connect();
		return con;
	}

	/**
	 * Extracts the url from a request
	 */
	private String getURL(HttpServletRequest req) {
		String query = ""; //$NON-NLS-1$
		boolean firstParam = true;
		for (Enumeration params = req.getParameterNames(); params
				.hasMoreElements();) {
			String param = (String) params.nextElement();
			String[] values = req.getParameterValues(param);
			if (values == null)
				continue;
			for (int i = 0; i < values.length; i++) {
				if (firstParam) {
					query += "?" + param + "=" + values[i]; //$NON-NLS-1$ //$NON-NLS-2$
					firstParam = false;
				} else
					query += "&" + param + "=" + values[i]; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		// the request contains the eclipse url help: or search:
		String url = req.getPathInfo() + query;
		if (url.startsWith("/")) //$NON-NLS-1$
			url = url.substring(1);
		return url;
	}

}
