//------------------------------------------------------------------------------
//Copyright (c) 2004, 2007 IBM Corporation.  All Rights Reserved.
//------------------------------------------------------------------------------
package org.eclipse.epf.web.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Locale;
import java.util.Properties;

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 javax.servlet.http.HttpSession;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.search.Hits;
import org.eclipse.epf.web.search.IndexLoader;
import org.eclipse.epf.web.search.IndexSearch;
import org.eclipse.epf.web.search.SearchResources;
import org.eclipse.epf.web.search.utils.StrUtil;
import org.eclipse.epf.web.search.utils.UNCUtil;
import org.eclipse.epf.web.search.utils.XMLUtil;
import org.eclipse.epf.web.search.utils.XSLTProcessor;

public class SearchServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	private int _hitsPerPage = 10;
	private static String _indexPath = null;
	private static String _xslURL;
	private static String _pathDocumentBase;
	private static String _siteFolderName = null;
	private String _currentSearchString;
	private String _queryString;
	private String _webAppName;
	private Hits _hits;
	private int _numHits;
	private int _currentPage;
	private String analyzerName;

	private HttpServletResponse _response;

	// Empty HTML.
	public static final String EMPTY_HTML = "<html></html>"; //$NON-NLS-1$

	private Properties xslParams = null;

	public void init(ServletConfig config) throws ServletException {
		super.init(config);

		try {
			_indexPath = config.getServletContext().getRealPath(
					config.getInitParameter("searchIndex"));
			_xslURL = config.getServletContext().getRealPath(
					config.getInitParameter("xslFile"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		HttpSession session = request.getSession();		
		
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();

		_response = response;
		request.setCharacterEncoding("UTF-8");
		String requestUrl = request.getRequestURL().toString();
		_pathDocumentBase = requestUrl.substring(0, requestUrl.lastIndexOf('/'));		

		try {
			_siteFolderName = IndexLoader.getSiteFolderName(_pathDocumentBase);
			analyzerName = IndexLoader.getAnalyzerName();
			
			synchronized(session) {
				String results;
				String action = request.getParameter("action");
				_webAppName = request.getContextPath();

				if (action != null && action.length() > 0) {
					
					_hits = (Hits) session.getAttribute("hits");					
					_queryString = (String) session.getAttribute("queryString");
					_numHits = ((Integer) session.getAttribute("numHits")).intValue();
					_currentPage = ((Integer) session.getAttribute("currentPage")).intValue();

					if (action.indexOf("next") > -1) {
						results = getPageResult(true);
						session.setAttribute("numHits", new Integer(_numHits));
						session.setAttribute("currentPage", new Integer(_currentPage));
						out.println(results);
					} else {
						results = getPageResult(false);
						session.setAttribute("numHits", new Integer(_numHits));
						session.setAttribute("currentPage", new Integer(_currentPage));
						out.println(results);
					}
				} else {
					String searchString = request.getParameter("searchString");
					System.out.println("LD> searchString: " + searchString);
					
					if (searchString == null || searchString.length() == 0) {
						response.sendError(HttpServletResponse.SC_NO_CONTENT);
						return;
					}
					//searchString = URLEncoder.encode(searchString, "UTF-8");

					String resultsPerPage = request.getParameter("hitsPerPage");
					if (resultsPerPage != null && resultsPerPage.length() > 0) {
						_hitsPerPage = Integer.parseInt(resultsPerPage);
					}
					results = runSearch(searchString);
					session.setAttribute("hits", _hits);
					session.setAttribute("queryString", _queryString);
					session.setAttribute("numHits", new Integer(_numHits));
					session.setAttribute("currentPage", new Integer(_currentPage));
					out.println(results);					
				}
			}

		} catch (Exception ex) {
			// ex.printStackTrace();
			writeOutputError(response.getOutputStream(), SearchResources
					.getString("SearchFailed"), ex);
		}
	}

	/**
	 * Performs the advanced search.
	 */
	private String runSearch(final String searchString) {

		try {

			_queryString = searchString.replace(':', ' '); // RATLC00251228

			_currentSearchString = IndexSearch.detectHyphenated(_queryString); // wordBuffer.toString();

			if (_currentSearchString.length() == 0) {
				return EMPTY_HTML;
			}

			boolean safe = runQuery("contents");

			String result = updateOutput(safe);

			return (result == null) ? EMPTY_HTML : result;

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

		return EMPTY_HTML;
	}

	private boolean runQuery(String searchField) {
		boolean result = false;
		//_currentSearchString = "\u57FA\u672C\u539F\u5247";
		try {
			System.out.println("LD> _indexPath: " + _indexPath);//$NON-NLS-1$
			System.out.println("LD> _currentSearchString: " + _currentSearchString);//$NON-NLS-1$
			if (_currentSearchString != null) {
				System.out.println("LD> unicodes: " + 
					escapeUnicodeString(_currentSearchString, false));//$NON-NLS-1$
			}
			
			System.out.println("LD> analyzerName: " + analyzerName);//$NON-NLS-1$
			
			_hits = IndexSearch.search(_indexPath, _currentSearchString, searchField, analyzerName);// new
			System.out.println("LD> _hits: " + 
					(_hits == null ? "null" : Integer.toString(_hits.length())));//$NON-NLS-1$ //$NON-NLS-2$
			
			// SortedHits(hits);

			_numHits = _hits.length();

			result = true;
		} catch (Exception e1) {
			e1.printStackTrace();
			_numHits = 0;
			_hits = null;
		}
		_currentPage = 0;

		return result;
	}

	/**
	 * Updates the results panel with the search output.
	 */
	private String updateOutput(boolean safe) {
		String output = null;

		if (safe) {
			output = generateOutput(_numHits, _currentPage);
		} else {
			_hits = null;
		}

		return output;
	}

	/**
	 * Generates the HTML representation for the given process search hits.
	 */
	private String generateOutput(int numHits, int pageNum) {
		int init = pageNum * _hitsPerPage;
		int max = Math.min(numHits, init + _hitsPerPage);
		boolean nextEnabled = numHits > (_currentPage + 1) * _hitsPerPage;
		boolean prevEnabled = _currentPage > 0;

		if (_hits == null) {
			return null;
		}
		try {

			StringBuffer searchResultXML = new StringBuffer();

			// encodeURL is just planning ahead in case this servlet is ever used in
			// an application that does session tracking. If cookies are turned off,
			// session tracking is usually accomplished by URL rewriting, so all URLs
			// returned by servlets should be sent through encodeURL.

			searchResultXML
					.append("<SearchResult") //$NON-NLS-1$
					.append(" totalHits=\"").append(numHits) //$NON-NLS-1$		
					.append("\" initPageNum=\"").append((init > 0) ? init + 1 : (numHits < 1) ? 0 : 1) //$NON-NLS-1$
					.append("\" maxPageNum=\"").append(max) //$NON-NLS-1$
					.append("\" hitsPerPage=\"").append(_hitsPerPage) //$NON-NLS-1$
					.append("\" nextEnabled=\"").append(nextEnabled) //$NON-NLS-1$
					.append("\" prevEnabled=\"").append(prevEnabled) //$NON-NLS-1$
					.append("\" nextText=\"").append(SearchResources.getString("nextActionText")) //$NON-NLS-1$
					.append("\" prevText=\"").append(SearchResources.getString("previousActionText")) //$NON-NLS-1$
					.append("\" imagePath=\"").append(_pathDocumentBase + "/search/images/") //$NON-NLS-1$
					.append("\" searchString=\"").append(XMLUtil.escape(_queryString)) //$NON-NLS-1$			
					.append("\" nextHref=\"").append(_response.encodeURL(_webAppName + "/SearchServlet?action=next")) //$NON-NLS-1$
					.append("\" prevHref=\"").append(_response.encodeURL(_webAppName + "/SearchServlet?action=prev")) //$NON-NLS-1$
					.append("\">"); //$NON-NLS-1$

			for (int i = init; i < max; i++) {
				Document doc = _hits.doc(i);
				Field url = doc.getField("url"); //$NON-NLS-1$
				Field title = doc.getField("title"); //$NON-NLS-1$
				Field summary = doc.getField("summary"); //$NON-NLS-1$
				Field umaType = doc.getField("uma.type"); //$NON-NLS-1$

				searchResultXML.append("<SearchHit"); //$NON-NLS-1$

				if (url != null) {
					StringBuffer bufferURL = new StringBuffer();
					String strUrl = url.stringValue();
					bufferURL.append(_pathDocumentBase).append(
							strUrl.substring(strUrl.indexOf(_siteFolderName)
									+ _siteFolderName.length()));

					if (strUrl != null) {
						strUrl = XMLUtil.escape(strUrl);
						searchResultXML.append(" url=\"") //$NON-NLS-1$
								.append(
										UNCUtil
												.convertFilenameToUNC(bufferURL
														.toString())).append("\""); //$NON-NLS-1$
					}
				}

				if (title != null) {
					String strTitle = title.stringValue();
					if (strTitle != null) {
						strTitle = XMLUtil.escape(strTitle);
						searchResultXML.append(" title=\"") //$NON-NLS-1$
								.append(strTitle).append("\""); //$NON-NLS-1$
					}
				}

				if (summary != null) {
					String strSummary = summary.stringValue();
					if (strSummary != null) {
						strSummary = XMLUtil.escape(strSummary);
						searchResultXML.append(" summary=\"") //$NON-NLS-1$
								.append(strSummary).append("\""); //$NON-NLS-1$
					}
				}

				if (umaType != null) {
					String[] keyWords = { "Product", "Descriptor", "Process", "Pattern",
							"Type", "Definition", "Asset", "Considerations", "Category", 
							"Material", "Grouping", "Set", "Tool" };

					String strUmaType = StrUtil.convertFirstLetterCase(umaType
							.stringValue(), keyWords);
					
					if (strUmaType.equalsIgnoreCase("General_content")) {
						searchResultXML.append(" icon=\"") //$NON-NLS-1$
							.append("Other.gif").append("\""); //$NON-NLS-1$
					} else {
						strUmaType = XMLUtil.escape(strUmaType);
						searchResultXML.append(" icon=\"") //$NON-NLS-1$
							.append(strUmaType).append(".gif").append("\""); //$NON-NLS-1$
					}					
				}
				searchResultXML.append("/>"); //$NON-NLS-1$	
			}

			searchResultXML.append("</SearchResult>"); //$NON-NLS-1$

			StringWriter result = new StringWriter();

			// System.out.println(searchResultXML.toString());

			XSLTProcessor.transform(_xslURL, searchResultXML.toString(), xslParams,
					result);

			//System.out.println(result.toString());

			return result.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return EMPTY_HTML;
		}
	}

	private String getPageResult(boolean isNext) {
		if (isNext)
			_currentPage++;
		else
			_currentPage--;
		String result = updateOutput(true);

		return (result == null) ? EMPTY_HTML : result;
	}

	private void writeOutputError(ServletOutputStream os, String message, Exception ex)
			throws ServletException {
		Throwable t = ex;
		System.out.println("Exceptio: " + ex);
		if (ex instanceof java.lang.reflect.InvocationTargetException)
			t = ((java.lang.reflect.InvocationTargetException) ex).getTargetException();
		try {
			os.println("<hr>" + message + "<hr>");
			t.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//for debug
	private static String escapeUnicodeString(String str, boolean escapeAscii) {
		StringBuffer ostr = new StringBuffer();

		for (int i = 0; i < str.length(); i++) {

			char ch = str.charAt(i);

			if (!escapeAscii && ((ch >= 0x0020) && (ch <= 0x007e))) {
				ostr.append(ch);
			} else {

				ostr.append("\\u") ;	//$NON-NLS-1$

				String hex = Integer.toHexString(str.charAt(i) & 0xFFFF);
				for (int j = 0; j < 4 - hex.length(); j++)
					ostr.append("0");//$NON-NLS-1$)

				ostr.append(hex.toUpperCase(Locale.ENGLISH));

			}

		}

	  return (new String(ostr));

	}

}