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

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.eclipse.epf.web.search.utils.UNCUtil;


public class IndexLoader {
	public static final String VERSION_FILE_NAME = "version.txt";
	public static final String VERSION_DELIMITER = "*";
	public static final String DOWNLOAD_ERROR = "Unable to download index.jar file";

	private static String userIndexFolderName = null;
	private String userIndexPath = null;
	private static String analyzerName;	
	private static Map cache = new HashMap();

	protected String m_docBase;
	protected String m_indexFolder;
	protected String m_indexFile;
	protected long tally;
	protected int fileSize;

	public String downloadIndex() {
		byte bytes[] = new byte[16384];

		String product = "";
		File versionFile = null;
		File indexArchive = null;

		try {
			// TBD replace 100 with something to do with archive size or
			// something
			StringBuffer base = new StringBuffer(m_docBase);
			base.append("/search/index/index.jar");


			URL url = new URL(base.toString());
			// handle UNC
			url = UNCUtil.handleURLForUNC(url);

			System.out.println("IndexLoader.downloadIndex index file: " + url.toString());

			// File folder = new File(m_indexFolder);
			// folder = folder.getParentFile();
			//
			// if (folder.exists())
			// {
			// folder.delete();
			// }

			indexArchive = new File(m_indexFile);
			indexArchive.getParentFile().mkdirs();
			
			System.out.println("IndexLoader.downloadIndex local index file: " + indexArchive.getAbsolutePath());

			StringBuffer newIndexFolderName = new StringBuffer(m_indexFolder);
			newIndexFolderName.append(userIndexFolderName);

			// let's get the attrbutes of the file we want to download.
			versionFile = new File(newIndexFolderName.toString()
					+ File.separator + VERSION_FILE_NAME);
			FileReader readVersion = new FileReader(versionFile);
			BufferedReader bRead = new BufferedReader(readVersion);
			String versionString = bRead.readLine();
			bRead.close();
			readVersion.close();
			StringTokenizer tok = new StringTokenizer(versionString,
					VERSION_DELIMITER);
			product = tok.nextToken();
			tok.nextToken();
			fileSize = Integer.parseInt(tok.nextToken());

			BufferedInputStream inputS = new BufferedInputStream(url
					.openStream());
			FileOutputStream writeArchive = new FileOutputStream(indexArchive);

			// System.out.println("docBase: " + m_docBase);

			tally = 0;
			int streamNotAvailable = 0;

			// System.out.println("Downloading index file: " + url.toString());
			// System.out.println("fileSize: " + fileSize);

			while (tally < fileSize) {
				int num = inputS.read(bytes);

				// inputS.available() is not implemented for some imput stream,
				// such as strem from https url. The value will always be 0
				if (/* inputS.available() */num > 0) {
					streamNotAvailable = 0;
					writeArchive.write(bytes, 0, num);
					tally = tally + num;
				} else {
					try {
						// this will cause invalid thread exeception
						// since the thread may not own the object's monitor
						// use synchronized key to force the thread to own the
						// object's monitor
						synchronized (this) {
							wait(50);
						}

						if (streamNotAvailable > 100) {
							System.out.println("time out: " + DOWNLOAD_ERROR);
							throw new Exception(DOWNLOAD_ERROR);
						}
						streamNotAvailable++;
					} catch (Exception e1) {
						System.out.println("Download index failed");
						// display.setText(display.getText() + "\nDownload index
						// failed");
						e1.printStackTrace();
						break;
					}
				}
			}

			inputS.close();
			writeArchive.close();
			tally = 0;

			ZipInputStream zStream = new ZipInputStream(new FileInputStream(
					m_indexFile));
			ZipEntry zEntry = zStream.getNextEntry();
			while (zEntry != null) {
				File file = new File(newIndexFolderName.toString(), zEntry
						.getName());

				if (zEntry.isDirectory()) {
					file.mkdir();
				} else {
					file.getParentFile().mkdirs();
					FileOutputStream outs = new FileOutputStream(file);
					while (zStream.available() > 0) {
						int num = zStream.read(bytes);
						if (num > 0) {
							outs.write(bytes, 0, num);
						}
					}
					outs.close();
					tally++;
				}

				zEntry = zStream.getNextEntry();
			}
			zStream.close();

			System.out
					.println("Completed writing the index files successfully");
		} catch (Exception e1) {
			System.out.println(e1.getMessage());
			product = null;
			versionFile.delete();

			e1.printStackTrace();
		} finally {
			if (indexArchive.exists())
				indexArchive.delete();

		}

		return product;
	}

	/**
	 * Constructor for IndexLoader
	 */
	public IndexLoader(String documentBase, String indexFolder, String indexFile) {
		m_docBase = documentBase;
		m_indexFolder = indexFolder;
		m_indexFile = indexFile;
		
		System.out.println("IndexLoader docBase: " + m_docBase);
		System.out.println("IndexLoader indexFolder: " + m_indexFolder);
		System.out.println("IndexLoader indexFile: " + m_indexFile);
		
	}

	/**
	 * Determines whether the index version is out of date.
	 */
	public String checkIndexVersion() throws Exception {
		String siteFolderName = null;

		try {
			URL url = new URL(m_docBase
					+ "/search/index/version.txt"); //$NON-NLS-1$
			// handle UNC
			url = UNCUtil.handleURLForUNC(url);

			System.out.println("IndexLoader.checkIndexVersion reading index file: " + url.toString());

			BufferedInputStream inputS = new BufferedInputStream(url
					.openStream());
			InputStreamReader iStreamReader = new InputStreamReader(inputS);
			BufferedReader read = new BufferedReader(iStreamReader);
			String version = read.readLine();
			int idx = (version != null) ? version.indexOf(VERSION_DELIMITER)
					: -1;
			if (idx > -1) {
				String localFolderName = version.substring(idx + 1);
				userIndexFolderName = removeChar(localFolderName, '*');
			} else {
				throw new FileNotFoundException();
			}
			
			String analyzer = read.readLine();
			if (analyzer != null) {
				analyzer = analyzer.trim();
			}
			setAnalyzerName(analyzer);
			
			read.close();
		
			if (userIndexFolderName == null) {
				throw new FileNotFoundException();
			}

			userIndexPath = m_indexFolder + userIndexFolderName;
			System.out.println("IndexLoader.checkIndexVersion userIndexPath: " + userIndexPath);

			String userStringVersion = ""; //$NON-NLS-1$
			File userVersion = new File(userIndexPath + File.separator
					+ "version.txt"); //$NON-NLS-1$
			
			System.out.println("IndexLoader.checkIndexVersion userVersion: " + userVersion.getAbsolutePath());

			if (userVersion.exists()) {
				FileReader fRead = new FileReader(userVersion);
				read = new BufferedReader(fRead);
				userStringVersion = read.readLine();
				read.close();
			}
			if (version.equals(userStringVersion)) {
				siteFolderName = userStringVersion.substring(0,
						userStringVersion.indexOf("*")); //$NON-NLS-1$
			} else {
				userVersion.delete();
				userVersion.getParentFile().delete();
				userVersion.getParentFile().mkdirs();
				FileWriter fWrite = new FileWriter(userVersion);
				BufferedWriter write = new BufferedWriter(fWrite);
				write.write(version + "\n"); //$NON-NLS-1$
				write.close();
			}
		} catch (FileNotFoundException e) {
			System.out.println("Error in IndexLoader.checkIndexVersion: " + e.getMessage());
			// try {
			// IndexBuilder indexBuilder = new IndexBuilder(pathDocumentBase);
			// indexBuilder.createIndex();
			// siteFolderName = checkIndexVersion(pathDocumentBase,
			// indexLocation);
			// return siteFolderName;
			// } catch (Exception e2) {
			// e2.printStackTrace();
			// }
		} catch (Exception e1) {
			System.out.println("Error in IndexLoader.checkIndexVersion: " + e1.getMessage());
			e1.printStackTrace();
		}

		return siteFolderName;
	}
	
	public static String getSiteFolderName(String documentBase) throws Exception {
		String siteFolderName = (String) cache.get(documentBase);
		
		if (siteFolderName != null)
			return siteFolderName;		

		try {
			URL url = new URL(documentBase + "/search/index/version.txt"); //$NON-NLS-1$
			// handle UNC
			url = UNCUtil.handleURLForUNC(url);

			BufferedInputStream inputS = new BufferedInputStream(url
					.openStream());
			InputStreamReader iStreamReader = new InputStreamReader(inputS);
			BufferedReader read = new BufferedReader(iStreamReader);
			String version = read.readLine();
			int idx = (version != null) ? version.indexOf(VERSION_DELIMITER)
					: -1;
			if (idx > -1) {
				siteFolderName = version.substring(0, idx);	
				cache.put(documentBase, siteFolderName);
			} else {
				throw new FileNotFoundException();
			}
			
			String analyzer = read.readLine();
			if (analyzer != null) {
				analyzer = analyzer.trim();
			}
			setAnalyzerName(analyzer);
			
			read.close();
		
			if (siteFolderName == null) {
				throw new FileNotFoundException();
			}			
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
		} catch (Exception e1) {
			e1.printStackTrace();
		}

		return siteFolderName;
	}
	
	public static String removeChar(String s, char c) {
		String r = "";
		for (int i = 0; i < s.length(); i++) {
			if (s.charAt(i) != c)
				r += s.charAt(i);
		}
		return r;
	}

	public String getUserIndexPath() {
		return userIndexPath;
	}

	public synchronized static String getAnalyzerName() {
		return analyzerName;
	}

	private synchronized static void setAnalyzerName(String analyzerName) {
		IndexLoader.analyzerName = analyzerName;
	}
}