//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.search.configuration.internal;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

import org.apache.lucene.document.DateField;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.epf.common.html.HTMLParser;
import org.eclipse.epf.search.GenerateSearchIndexException;
import org.eclipse.epf.search.SearchConfigurationException;
import org.eclipse.epf.search.SearchResources;
import org.eclipse.epf.search.SearchServiceException;
import org.eclipse.epf.search.analysis.TextAnalyzer;
import org.eclipse.epf.search.configuration.ConfigurationHitEntry;
import org.eclipse.epf.search.configuration.ConfigurationSearchQuery;

/**
 * The default implementation for searching a published configuration.
 * 
 * @author Kelvin Low
 * @since 1.0
 */
public class ConfigurationSearchService {

	/**
	 * Document fields.
	 */
	public static final String BRIEF_DESCRIPTION_FIELD = "briefDescription"; //$NON-NLS-1$

	public static final String CONTENT_FIELD = "content"; //$NON-NLS-1$

	public static final String ID_FIELD = "id"; //$NON-NLS-1$

	public static final String MODIFIED_FIELD = "modified"; //$NON-NLS-1$

	public static final String NAME_FIELD = "name"; //$NON-NLS-1$

	public static final String ROLE_FIELD = "role"; //$NON-NLS-1$

	public static final String SUMMARY_FIELD = "summary"; //$NON-NLS-1$

	public static final String TYPE_FIELD = "type"; //$NON-NLS-1$

	public static final String URL_FIELD = "url"; //$NON-NLS-1$

	// The HTML parser.
	private HTMLParser parser;

	// The directory containing the documents to be indexed.
	private String docDir = null;

	// The directory where the index files will be generated.
	private String indexDir = null;

	/**
	 * Creates a new instance.
	 * 
	 * @param docDir
	 *            the absolute path to a published configuration
	 */
	public ConfigurationSearchService(String docDir) {
		String userHome = System.getProperty("user.home"); //$NON-NLS-1$
		int hashCode = Math.abs(docDir.hashCode());
		String indexPath = userHome + File.separator
				+ "rup" + File.separator + hashCode + File.separator + "index"; //$NON-NLS-1$ //$NON-NLS-2$
		setDirs(docDir, indexPath);
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param docDir
	 *            the absolute path to a published configuration
	 * @param indexDir
	 *            the absolute path to the indexes
	 */
	public ConfigurationSearchService(String docDir, String indexDir) {
		setDirs(docDir, indexDir);
	}

	/**
	 * Sets up the configuration and index directory.
	 * 
	 * @param docDir
	 *            the absolute path to a published configuration
	 * @param indexDir
	 *            the absolute path to the indexes
	 */
	public void setDirs(String docDir, String indexDir) {
		this.docDir = docDir;
		this.indexDir = indexDir;
	}

	/**
	 * Performs a search based on the given search query.
	 * 
	 * @param query
	 *            the search query string
	 * @return an array of <code>ConfigurationHitEntry</code> objects
	 * @throws SearchServiceException
	 *             if an error occurs while executing the operation
	 */
	public ConfigurationHitEntry[] search(ConfigurationSearchQuery query)
			throws SearchServiceException {
		return search(query.getQueryString());
	}

	/**
	 * Performs a search on the given query string.
	 * 
	 * @param qstr
	 *            a Lucene compatible query string
	 * @return an array of <code>ConfigurationHitEntry</code> objects
	 * @throws SearchServiceException
	 *             if an error occurs while executing the operation
	 */
	public ConfigurationHitEntry[] search(String qstr)
			throws SearchServiceException {
		Searcher searcher = null;
		try {
			searcher = new IndexSearcher(indexDir);
			Query query = QueryParser.parse(qstr, CONTENT_FIELD,
					new TextAnalyzer());

			Hits lhits = searcher.search(query);
			ConfigurationHitEntry[] hits = new ConfigurationHitEntry[lhits
					.length()];

			for (int i = 0; i < hits.length; i++) {
				Document doc = lhits.doc(i);
				hits[i] = new ConfigurationHitEntry();
				hits[i].setName(doc.get(NAME_FIELD));
				hits[i].setUrl(doc.get(URL_FIELD));
				hits[i].setBriefDesc(doc.get(BRIEF_DESCRIPTION_FIELD));
				hits[i].setId(doc.get(ID_FIELD));
				hits[i].setType(doc.get(TYPE_FIELD));
			}
			return hits;
		} catch (Exception e) {
			throw new SearchConfigurationException(e);
		} finally {
			if (searcher != null) {
				try {
					searcher.close();
				} catch (IOException e) {
				}
			}
		}
	}

	/**
	 * Returns true of the index database already exists.
	 * 
	 * @return <code>true</code> if the index database already exists
	 */
	public boolean indexExists() {
		File[] files = new File(indexDir).listFiles();
		return (files != null && files.length != 0);
	}

	/**
	 * Creates the search index.
	 * 
	 * @throws SearchServiceException
	 *             if an error occurs while executing the operation
	 */
	public void index() throws SearchServiceException {
		index(null, false);
	}

	/**
	 * Creates the search index.
	 * 
	 * @param reindex
	 *            if <code>true</code>, performs a reindex
	 * @throws SearchServiceException
	 *             if an error occurs while executing the operation
	 */
	public void index(boolean reindex) throws SearchServiceException {
		index(null, reindex);
	}

	/**
	 * Creates the index database.
	 * 
	 * @param pm
	 *            a progress monitor
	 * @param reindex
	 *            if <code>true</code>, performs a reindex
	 * @throws SearchServiceException
	 *             if an error occurs while executing the operation
	 */
	public void index(IProgressMonitor pm, boolean reindex)
			throws SearchServiceException {
		synchronized (ConfigurationSearchService.class) {
			if (indexDir == null || docDir == null) {
				throw new IllegalStateException("Invalid indexDir or docDir"); //$NON-NLS-1$
			}

			if (!reindex && indexExists()) {
				return;
			}

			if (pm != null) {
				pm.beginTask(SearchResources.indexConfigFilesTask_name,
						getTotalDocsToIndex(docDir)); //$NON-NLS-1$
			}

			try {
				deleteAllIndexDirs();
				new File(indexDir).mkdirs();
				IndexWriter writer = new IndexWriter(indexDir,
						new TextAnalyzer(), true);
				writer.maxFieldLength = 1000000;
				parser = new HTMLParser();
				indexDocs(new File(docDir), writer, pm);
				writer.optimize();
				writer.close();
			} catch (Exception e) {
				throw new GenerateSearchIndexException(e);
			} finally {
				if (pm != null) {
					pm.done();
				}
			}
		}
	}

	/**
	 * Deletes all existing index databases.
	 */
	public void deleteAllIndexDirs() {
		File parent = new File(indexDir).getParentFile();
		File[] files = parent.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				if (files[i].getName().startsWith("index")) { //$NON-NLS-1$
					File[] file = files[i].listFiles();
					for (int j = 0; j < file.length; j++) {
						file[j].delete();
					}
					files[i].delete();
				}
			}
		}
	}

	/**
	 * Returns the total number of files that will be added to the search index.
	 * 
	 * @param dir
	 *            the directory name
	 * @return the number of files that will be added to the search index,
	 *         including all sub-directories
	 */
	public static int getTotalDocsToIndex(String dir) {
		int total = 0;
		File dirFile = new File(dir);
		File files[] = dirFile.listFiles();
		if (files == null) {
			return total;
		}
		for (int i = 0; i < files.length; i++) {
			if (isXMIDoc(files[i])) {
				total++;
			} else if (files[i].isDirectory()) {
				total += getTotalDocsToIndex(files[i].getAbsolutePath());
			}
		}
		return total;
	}

	/**
	 * Returns true if the file needs to be indexed.
	 * 
	 * @param file
	 *            the file to be verified
	 * @return <code>true</code> if the file needs to be indexed
	 */
	private static boolean isXMIDoc(File file) {
		return file.getPath().endsWith(".xmi"); //$NON-NLS-1$
	}

	/**
	 * Returns true if the file needs to be indexed.
	 * 
	 * @param file
	 *            the file to be verified
	 * @return <code>true</code> if the file needs to be indexed
	 */
	private static boolean isHtmlOrTextDoc(File file) {
		String path = file.getPath();
		return path.endsWith(".html") || path.endsWith(".htm") || path.endsWith(".txt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	/**
	 * A recursive function to index files.
	 * 
	 * @param file
	 *            a directory or file to be indexed
	 * @param writer
	 *            the index writer
	 * @param pm
	 *            a progress monitor
	 * @throws Exception
	 */
	private void indexDocs(File file, IndexWriter writer, IProgressMonitor pm)
			throws Exception {
		if (file.isDirectory()) {
			if (file.getName().equalsIgnoreCase("applet")) { //$NON-NLS-1$
				return;
			}
			String[] files = file.list();
			for (int i = 0; i < files.length; i++) {
				indexDocs(new File(file, files[i]), writer, pm);
			}
		} else if (isHtmlOrTextDoc(file)) {
			if (pm != null) {
				pm.subTask(file.getName());
				pm.worked(1);
			}
			if (shouldBeExcluded(file)) {
				return;
			}
			Document doc = getHTMLDocument(file);
			writer.addDocument(doc);
		}
	}

	/**
	 * Returns <ocde>true</code> if the file should be excluded from indexing.
	 * 
	 * @param file
	 *            a file
	 * @return <code>true</code> if the file should be excluded from indexing
	 */
	public boolean shouldBeExcluded(File file) {
		String p = file.getParentFile().getAbsolutePath();
		return docDir.startsWith(p);
	}

	/**
	 * Gets the document object of a HTML file.
	 * 
	 * @param file
	 *            the HTML file to be indexed
	 * @return a document object
	 * @throws IOException
	 *             if an I/O error occurs while parsing the HTML file
	 * @throws InterruptedException
	 *             if the operation is interrupted by a user
	 */
	public Document getHTMLDocument(File file) throws IOException,
			InterruptedException {
		Document doc = new Document();
		doc.add(Field.UnIndexed(URL_FIELD, file.getPath().replace(
				File.pathSeparatorChar, '/')));
		doc.add(Field.Keyword(MODIFIED_FIELD, DateField.timeToString(file
				.lastModified())));

		try {
			parser.parse(file);
		} catch (Exception e) {
		}

		doc.add(Field.Text(CONTENT_FIELD, parser.getText()));
		doc.add(Field.UnIndexed(SUMMARY_FIELD, parser.getSummary()));

		Properties metaTags = parser.getMetaTags();
		for (Enumeration e = metaTags.propertyNames(); e.hasMoreElements();) {
			String tagName = (String) e.nextElement();
			doc.add(Field.Text(tagName, metaTags.getProperty(tagName)));
		}

		if (doc.getField(ROLE_FIELD) == null) {
			doc.add(Field.Text(ROLE_FIELD, "NORUPROLE")); //$NON-NLS-1$
		}

		return doc;
	}

}