/*******************************************************************************
 * Copyright (c) 2004 - 2006 University Of British Columbia 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:
 *     University Of British Columbia - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylar.internal.monitor;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.eclipse.mylar.internal.core.MylarContextExternalizer;
import org.eclipse.mylar.internal.core.util.MylarStatusHandler;
import org.eclipse.mylar.internal.core.util.XmlStringConverter;
import org.eclipse.mylar.internal.monitor.HtmlStreamTokenizer.Token;
import org.eclipse.mylar.provisional.core.IInteractionEventListener;
import org.eclipse.mylar.provisional.core.InteractionEvent;
import org.eclipse.mylar.provisional.core.InteractionEvent.Kind;

/**
 * @author Mik Kersten
 * @author Ken Sueda (XML serialization)
 * 
 * TODO: use buffered output stream for better performance?
 */
public class InteractionEventLogger implements IInteractionEventListener {

	private File outputFile;

	private static FileOutputStream outputStream;

	private boolean started = false;

	private int eventAccumulartor = 0;

	private List<InteractionEvent> queue = new ArrayList<InteractionEvent>();
	
	private HandleObfuscator handleObfuscator = new HandleObfuscator();

	public InteractionEventLogger(File outputFile) {
		this.outputFile = outputFile;
	}

	/**
	 * TODO: should these be queued for better performance?
	 */
	public void interactionObserved(InteractionEvent event) {
//		System.err.println(">>> " + event);
		if (handleObfuscator.isObfuscationEnabled()) {
			String obfuscatedHandle = handleObfuscator.obfuscateHandle(event.getStructureKind(), event.getStructureHandle());
			event = new InteractionEvent(event.getKind(), event.getStructureKind(), obfuscatedHandle, event.getOriginId(), event.getNavigation(), event.getDelta(), event.getInterestContribution());
		}
		try {
			if (started) {
				String xml = interactionEventToXml(event);
				outputStream.write(xml.getBytes());
			} else {
				queue.add(event);
			}
			eventAccumulartor++;
		} catch (NullPointerException e) {
			MylarStatusHandler.log(e, "could not log interaction event");
		} catch (Throwable t) {
			MylarStatusHandler.log(t, "could not log interaction event");
		}
	}

	public void startObserving() {
		try {
			if (!outputFile.exists())
				outputFile.createNewFile();
			outputStream = new FileOutputStream(outputFile, true);
			started = true;

			for (InteractionEvent queuedEvent : queue)
				interactionObserved(queuedEvent);
			queue.clear();
		} catch (FileNotFoundException e) {
			MylarStatusHandler.log(e, "could not resolve file");
		} catch (Throwable t) {
			MylarStatusHandler.log(t, "could not create new file");
		}
	}

	public void stopObserving() {
		try {
			if (outputStream != null) {
				outputStream.flush();
				outputStream.close();
			}
			started = false;
			if (MylarMonitorPlugin.getDefault() != null)
				MylarMonitorPlugin.getDefault().incrementObservedEvents(eventAccumulartor);
			eventAccumulartor = 0;
		} catch (IOException e) {
			MylarStatusHandler.fail(e, "could not close interaction event stream", false);
		}
	}

	public File moveOutputFile(String newPath) {
		stopObserving();
		File newFile = new File(newPath);
		try {
			if (outputFile.exists() && !newFile.exists()) {
				outputFile.renameTo(newFile);
			} else if (!newFile.exists()) {
				newFile.createNewFile();
				outputFile.delete();
			} else {
				outputFile.delete();
			}
			this.outputFile = newFile;
		} catch (Exception e) {
			MylarStatusHandler.fail(e, "Could not set logger output file", true);
		}
		startObserving();
		return newFile;
	}

	/**
	 * @return true if successfully cleared
	 */
	public synchronized void clearInteractionHistory() throws IOException {
		stopObserving();
		outputStream = new FileOutputStream(outputFile, false);
		outputStream.flush();
		outputStream.close();
		outputFile.delete();
		outputFile.createNewFile();
		startObserving();
	}

	public File getOutputFile() {
		return outputFile;
	}

	public List<InteractionEvent> getHistoryFromFile(File file) {
		List<InteractionEvent> events = new ArrayList<InteractionEvent>();
		try {
			// The file may be a zip file...
			if (file.getName().endsWith(".zip")) {
				ZipFile zip = new ZipFile(file);
				if (zip.entries().hasMoreElements()) {
					ZipEntry entry = zip.entries().nextElement();
					getHistoryFromStream(zip.getInputStream(entry), events);
				}
			} else {
				InputStream reader = new FileInputStream(file);
				getHistoryFromStream(reader, events);
				reader.close();
			}

		} catch (Exception e) {
			MylarStatusHandler.log("could not read interaction history", this);
			e.printStackTrace();
		}
		return events;
	}

	/**
	 * @param events
	 * @param tag
	 * @param endl
	 * @param buf
	 */
	private void getHistoryFromStream(InputStream reader, List<InteractionEvent> events) throws IOException {
		String xml;
		int index;
		String buf = "";
		String tag = "</" + MylarContextExternalizer.ELMNT_INTERACTION_HISTORY_OLD + ">";
		String endl = "\r\n";
		byte[] buffer = new byte[1000];
		int bytesRead = 0;
		while ((bytesRead = reader.read(buffer)) != -1) {
			buf = buf + new String(buffer, 0, bytesRead);
			while ((index = buf.indexOf(tag)) != -1) {
				index += tag.length();
				xml = buf.substring(0, index);
				InteractionEvent event = readEvent(xml);
				if (event != null)
					events.add(event);

				if (index + endl.length() > buf.length()) {
					buf = "";
				} else {
					buf = buf.substring(index + endl.length(), buf.length());
				}
			}
			buffer = new byte[1000];
		}
	}

	private static final String OPEN = "<";

	private static final String CLOSE = ">";

	private static final String SLASH = "/";

	private static final String ENDL = "\n";

	private static final String TAB = "\t";

	public String interactionEventToXml(InteractionEvent e) {
		StringBuffer res = new StringBuffer();
		String tag = "interactionEvent";
		String f = "yyyy-MM-dd HH:mm:ss.S z";
		SimpleDateFormat format = new SimpleDateFormat(f, Locale.ENGLISH);
		res.append(OPEN + tag + CLOSE + ENDL);
		res.append(TAB + OPEN + "kind" + CLOSE + e.getKind().toString() + OPEN + SLASH + "kind" + CLOSE + ENDL);
		res.append(TAB + OPEN + "date" + CLOSE + format.format(e.getDate()) + OPEN + SLASH + "date" + CLOSE + ENDL);
		res.append(TAB + OPEN + "endDate" + CLOSE + format.format(e.getEndDate()) + OPEN + SLASH + "endDate" + CLOSE
				+ ENDL);
		res.append(TAB + OPEN + "originId" + CLOSE + XmlStringConverter.convertToXmlString(e.getOriginId()) + OPEN
				+ SLASH + "originId" + CLOSE + ENDL);
		res.append(TAB + OPEN + "structureKind" + CLOSE + XmlStringConverter.convertToXmlString(e.getStructureKind())
				+ OPEN + SLASH + "structureKind" + CLOSE + ENDL);
		res.append(TAB + OPEN + "structureHandle" + CLOSE
				+ XmlStringConverter.convertToXmlString(e.getStructureHandle()) + OPEN + SLASH + "structureHandle"
				+ CLOSE + ENDL);
		res.append(TAB + OPEN + "navigation" + CLOSE + XmlStringConverter.convertToXmlString(e.getNavigation()) + OPEN
				+ SLASH + "navigation" + CLOSE + ENDL);
		res.append(TAB + OPEN + "delta" + CLOSE + XmlStringConverter.convertToXmlString(e.getDelta()) + OPEN + SLASH
				+ "delta" + CLOSE + ENDL);
		res.append(TAB + OPEN + "interestContribution" + CLOSE + "" + e.getInterestContribution() + OPEN + SLASH
				+ "interestContribution" + CLOSE + ENDL);
		res.append(OPEN + SLASH + tag + CLOSE + ENDL);
		return res.toString();
	}

	public InteractionEvent readEvent(String xml) {
		Reader reader = new StringReader(xml);
		HtmlStreamTokenizer tokenizer = new HtmlStreamTokenizer(reader, null);
		String kind = "";
		String startDate = "";
		String endDate = "";
		String originId = "";
		String structureKind = "";
		String structureHandle = "";
		String navigation = "";
		String delta = "";
		String interest = "";
		try {
			for (Token token = tokenizer.nextToken(); token.getType() != Token.EOF; token = tokenizer.nextToken()) {
				if (token.getValue().toString().equals("<kind>")) {
					token = tokenizer.nextToken();
					if (!token.getValue().toString().equals("</kind>")) {
						kind = token.getValue().toString().toLowerCase();
						token = tokenizer.nextToken();
					}
				} else if (token.getValue().toString().equals("<date>")) {
					token = tokenizer.nextToken();
					while (!token.getValue().toString().equals("</date>")) {
						startDate += token.getValue().toString() + " ";
						token = tokenizer.nextToken();
					}
					startDate.trim();
				} else if (token.getValue().toString().equals("<endDate>")) {
					token = tokenizer.nextToken();
					while (!token.getValue().toString().equals("</endDate>")) {
						endDate += token.getValue().toString() + " ";
						token = tokenizer.nextToken();
					}
					endDate.trim();
				} else if (token.getValue().toString().equals("<originId>")) {
					token = tokenizer.nextToken();
					originId = XmlStringConverter.convertXmlToString(token.getValue().toString());
					token = tokenizer.nextToken();
				} else if (token.getValue().toString().equals("<structureKind>")) {
					token = tokenizer.nextToken();
					while (!token.getValue().toString().equals("</structureKind>")) {
						if (structureKind.equals("")) {
							structureKind += token.getValue().toString();
						} else {
							structureKind += " " + token.getValue().toString();
						}
						token = tokenizer.nextToken();
					}
					structureKind = XmlStringConverter.convertXmlToString(structureKind);
				} else if (token.getValue().toString().equals("<structureHandle>")) {
					token = tokenizer.nextToken();
					while (!token.getValue().toString().equals("</structureHandle>")) {
						if (structureHandle.equals("")) {
							structureHandle += token.getValue().toString();
						} else {
							structureHandle += " " + token.getValue().toString();
						}
						token = tokenizer.nextToken();
					}
					structureHandle = XmlStringConverter.convertXmlToString(structureHandle);
				} else if (token.getValue().toString().equals("<navigation>")) {
					token = tokenizer.nextToken();
					while (!token.getValue().toString().equals("</navigation>")) {
						if (navigation.equals("")) {
							navigation += token.getValue().toString();
						} else {
							navigation += " " + token.getValue().toString();
						}
						token = tokenizer.nextToken();
					}
					navigation = XmlStringConverter.convertXmlToString(navigation);
					navigation.trim();
				} else if (token.getValue().toString().equals("<delta>")) {
					token = tokenizer.nextToken();
					while (!token.getValue().toString().equals("</delta>")) {
						if (delta.equals("")) {
							delta += token.getValue().toString();
						} else {
							delta += " " + token.getValue().toString();
						}
						token = tokenizer.nextToken();
					}
					delta = XmlStringConverter.convertXmlToString(delta);
					delta.trim();
				} else if (token.getValue().toString().equals("<interestContribution>")) {
					token = tokenizer.nextToken();
					interest = XmlStringConverter.convertXmlToString(token.getValue().toString());
					token = tokenizer.nextToken();
				}
			}
			String formatString = "yyyy-MM-dd HH:mm:ss.S z";
			SimpleDateFormat format = new SimpleDateFormat(formatString, Locale.ENGLISH);
			float interestFloatVal = 0;
			try {
				interestFloatVal = Float.parseFloat(interest);
			} catch (NumberFormatException nfe) {
				// ignore for empty interest values
			}
			InteractionEvent event = new InteractionEvent(Kind.fromString(kind), structureKind, structureHandle, originId,
					navigation, delta, interestFloatVal, format.parse(startDate), format.parse(endDate));
			return event;

		} catch (ParseException e) {
			System.err.println("readevent: " + xml);
			e.printStackTrace();
		} catch (IOException e) {
			System.err.println("readevent: " + xml);
			e.printStackTrace();
		} catch (Exception e) {
			System.err.println("readevent: " + xml);
			e.printStackTrace();
		}

		return null;
	}
}
