/*******************************************************************************
 * Copyright (c) 2000, 2009 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.util.*;

import javax.servlet.http.*;

import org.eclipse.core.runtime.Platform;
import org.eclipse.help.internal.base.HelpBasePlugin;
import org.eclipse.help.internal.webapp.data.*;
import org.eclipse.help.webapp.IFilter;

public class HighlightFilter implements IFilter {
	private static final String HIGHLIGHT_ON = "highlight-on"; //$NON-NLS-1$
	
	private static final String scriptPart1 = "\n<script type=\"text/javascript\">\n<!--\nvar keywords = new Array ("; //$NON-NLS-1$
	private static final String scriptPart2 = ");\nvar pluginDefault = "; //$NON-NLS-1$
	private static final String scriptPart3 = ";\n-->\n</script>\n<script type=\"text/javascript\" src=\""; //$NON-NLS-1$
	private static final String scriptPart5 = "advanced/highlight.js\"></script>\n"; //$NON-NLS-1$

	private static final String sheetRefPart1 = "<link id=\"highlightStyle\" rel=\"STYLESHEET\" href=\""; //$NON-NLS-1$
	private static final String sheetRefPart3 = "advanced/highlight.css\" charset=\"ISO-8859-1\" type=\"text/css\"></link>\n"; //$NON-NLS-1$
	
	/*
	 * @see IFilter#filter(HttpServletRequest, OutputStream)
	 */
	@Override
	public OutputStream filter(HttpServletRequest req, OutputStream out) {
		String uri = req.getRequestURI();
		if (uri == null) {
			return out;
		}
		if (!(UrlUtil.isIE(req) || UrlUtil.isMozilla(req))) {
			return out;
		}

		Collection<String> keywords = getWords(req);
		if (keywords.size() == 0) {
			return out;
		}
		keywords = removeWildCards(keywords);
		keywords = encodeKeyWords(keywords);
		byte[] script = createJScript(req, keywords);
		if (script == null) {
			return out;
		}

		return new FilterHTMLHeadOutputStream(out, script);
	}

	/**
	 * Creates Java Script that does highlighting
	 * 
	 * @param keywords
	 * @return byte[]
	 */
	private byte[] createJScript(HttpServletRequest req, Collection<String> keywords) {
		StringBuffer buf = new StringBuffer(scriptPart1);
		StringBuffer buf2 = new StringBuffer(sheetRefPart1);
		// append comma separated list of keywords
		Iterator<String> it = keywords.iterator();
		if (!it.hasNext())
			return null;
		String keyword = it.next();
		buf.append("\"").append(keyword).append("\""); //$NON-NLS-1$ //$NON-NLS-2$
		while (it.hasNext()) {
			keyword = it.next();
			buf.append(", \"").append(keyword).append("\""); //$NON-NLS-1$ //$NON-NLS-2$
		}
		buf.append(scriptPart2);
		buf.append(Platform.getPreferencesService().getBoolean
				(HelpBasePlugin.PLUGIN_ID, HIGHLIGHT_ON, false, null));
		buf.append(scriptPart3);
		// append "../" to get to the webapp
		String path = FilterUtils.getRelativePathPrefix(req);
		buf.append(path);
		buf2.append(path);
		
		buf.append(scriptPart5);
		buf.append(buf2.toString());
		buf.append(sheetRefPart3);
		try {
			return buf.toString().getBytes("ASCII"); //$NON-NLS-1$
		} catch (UnsupportedEncodingException uee) {
			return new byte[0];
		}
	}
	
	/**
	 * Extracts keywords from query that contains keywords dobule quoted and
	 * separated by space
	 * 
	 * @return Collection of String
	 */
	private Collection<String> getWords(HttpServletRequest req) {
		// Collect words to hash set to eliminate duplcates
		Collection<String> tokens = new ArrayList<String>();

		String searchWord = req.getParameter("resultof"); //$NON-NLS-1$
		if (searchWord == null) {
			return tokens;
		}
		//Divide along quotation marks
		StringTokenizer qTokenizer = new StringTokenizer(searchWord.trim(),
				"\"", true); //$NON-NLS-1$
		boolean withinQuotation = false;
		String quotedString = ""; //$NON-NLS-1$
		while (qTokenizer.hasMoreTokens()) {
			String curToken = qTokenizer.nextToken();
			if (curToken.equals("\"")) { //$NON-NLS-1$
				if (!withinQuotation) {
					//beginning of quoted string
					quotedString = ""; //$NON-NLS-1$
				} else {
					//end of quoted string
					tokens.add(quotedString);
				}
				withinQuotation = !withinQuotation;
				continue;
			}
			if (withinQuotation) {
				tokens.add(curToken);
			}
		}

		return tokens;

	}
	/**
	 * Encodes strings inside collection for embedding in HTML source
	 * 
	 * @return Collection of String
	 */
	private Collection<String> encodeKeyWords(Collection<String> col) {
		if (col == null)
			return col;
		Collection<String> result = new ArrayList<String>();
		for (String word : col) {
			int l = word.length();
			if (l < 1)
				continue;
			result.add(UrlUtil.JavaScriptEncode(word));
		}
		return result;
	}

	/**
	 * Removes wildcard characters from words, by splitting words around wild
	 * cards
	 * 
	 * @return Collection of String
	 */
	private Collection<String> removeWildCards(Collection<String> col) {
		if (col == null)
			return col;

		// Split words into parts: before "*" and after "*"
		Collection<String> resultPass1 = new ArrayList<String>();
		for (String word : col) {
			int index;
			while ((index = word.indexOf("*")) >= 0) { //$NON-NLS-1$
				if (index > 0)
					resultPass1.add(word.substring(0, index));
				if (word.length() > index)
					word = word.substring(index + 1);
			}
			if (word.length() > 0)
				resultPass1.add(word);
		}

		// Split words into parts: before "?" and after "?"
		Collection<String> resultPass2 = new ArrayList<String>();
		for (String word : resultPass1) {
			int index;
			while ((index = word.indexOf("?")) >= 0) { //$NON-NLS-1$
				if (index > 0)
					resultPass2.add(word.substring(0, index));
				if (word.length() > index)
					word = word.substring(index + 1);
			}
			if (word.length() > 0)
				resultPass2.add(word);
		}

		return resultPass2;
	}
}
