/*
 * $Id: EmlDocConverter.java,v 1.8 2006/06/06 20:36:03 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: EmlDocConverter.java,v $
 * Revision 1.8  2006/06/06 20:36:03  marbobo
 * + Mögliche NPE abgefangen
 *
 * Revision 1.7  2006/04/07 09:55:38  korowa
 * *** empty log message ***
 *
 * Revision 1.5  2004/11/10 15:02:44  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.4  2004/06/27 17:12:47  marbobo
 * + Quellcode maintenance
 *
 * Revision 1.3  2004/04/21 12:53:01  lawern
 * gangbar gemacht
 *
 * Revision 1.2  2004/04/08 19:15:27  teng
 * *** empty log message ***
 *
 * Revision 1.1  2004/04/08 16:26:30  teng
 * *** empty log message ***
 *

 */
package vkc.converter;

import vkc.misc.VKCLogManager;

import vkc.util.Eml2Html;
import vkc.util.FileUtils;
import vkc.util.VKCInputStream;
import vkc.util.ZipUtils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import java.net.URL;

import java.util.ArrayList;
import java.util.Collection;

/**
 * Klasse zum Konvertieren von Emaildokumenten.
 *
 * @author lawern
 */
public class EmlDocConverter extends DocConverter {
	private static final boolean debug = false;

	public static String docSuffix = ".eml";

	private File zipFile = null;

	private String htmlFile = null;

	private File emlDir = null;

	private File pdfFile = null;

	private HtmlDocConverter htmlConverter = null;

	public EmlDocConverter() {
	}

	/**
	 * Liefert den Suffix für temporäre Dateien zurück.
	 *
	 * @return docSuffix
	 */
	public String getDocSuffix() {
		return docSuffix;
	}

	/**
	 * Diese Methode konvertiert das übergebene Dokument in die in der
	 * Collection definierten Formate. Der Parameter conversions wird zur Zeit
	 * noch nicht ausgewertet.
	 *
	 * @param docFile URL des zu konvertierendes Dokument
	 * @param conversions Collection von VKCDocumentTypes welche die zu
	 *        erzeugenden Konvertierungen beschreibt.
	 */
	// HTML-Konvertierung muss auf jedenfall passieren, da andere Formate aus HTML generiert werden
	public void convert(URL docFile, Collection conversions) {
		if (debug) {
			System.out.println("EmlDocConverter: " + docFile);
		}

		if (conversions != null) {
			if (conversions.contains("EnableHTML")) {
				enableHtml = true;
			}
			
			if (conversions.contains("EnableTDF")) {
				enableTdf = true;
			}
			
			if (conversions.contains("EnablePDF")) {
				enablePdf = true;
			}
		}

		InputStream docStream = null;
		File tmpFile = null;

		try {
			//Datei von Url in temporäre Datei schreiben
			docStream = docFile.openStream();
			tmpFile = File.createTempFile("messageDoc", ".eml");

			if (!debug) {
				tmpFile.deleteOnExit();
			}

			FileUtils.saveInputStream(tmpFile, docStream, true);
			FileUtils.closeInputStream(docStream);

			//hier das ZIP-File erzeugen
			if (enableHtml || enableTdf || enablePdf) {// TDF- und PDF-Streams werden aus HTML erzeugt
				Eml2Html eml2html = new Eml2Html(tmpFile);

				eml2html.doEml2Html();

				emlDir = eml2html.getDirectory();

				htmlFile = emlDir.getCanonicalPath() + File.separator + "index.html";

				FileUtils.deleteZeroByteFile(new File(htmlFile));

				try {
					//Html-Version zusammenzipen
					zipFile = File.createTempFile("messageDoc", ".zip");

					if (!debug) {
						zipFile.deleteOnExit();
					}

					ZipUtils.zip(emlDir, zipFile, true, emlDir.getCanonicalPath() + File.separator);
				} catch (java.io.IOException ioe) {
					VKCLogManager.errorLog(this, "4", "Can't create temp-file.", ioe);
				}
			}
			
			//TDL-Stream erzeugen
			//Der übergeben null-Parameter muss später durch eine Collection ersetzt werden,
			//welche dafür sorgt, dass nur ein Tdf-Stream erzeugt wird!!!
			if (enableTdf) {
				htmlConverter = new HtmlDocConverter();
				htmlConverter.convert(new File(htmlFile).toURL(), null);
			}
			
			//PDF-Stream erzeugen.Geht nur mit OO
			if (enablePdf && openOffice) {
				try {
					pdfFile = File.createTempFile("temp", ".pdf");
					
					if (!debug) {
						pdfFile.deleteOnExit();
					}
					
					String[] convertTypes = new String[1];
					convertTypes[0] = "writer_web_pdf_Export";

					URL[] urls = new URL[1];
					urls[0] = pdfFile.toURL();

					new SOfficeDocConverter().convert(new File(htmlFile).toURL(), convertTypes, urls);
				} catch (IOException e1) {
					VKCLogManager.errorLog(this, "", e1.getMessage(), e1);
				}

				//Html-Verzeichnis löschen
				try {
					FileUtils.deleteDirectory(emlDir);
				} catch (Exception ex) {
					VKCLogManager.errorLog(this, "5", "Can't delete temp-dir.", ex);
				}
			}
		} catch (IOException ioex) {
			VKCLogManager.errorLog(this, "6", ioex.getMessage(), ioex);
		}
	}

	/**
	 * Liefert nach dem Aufruf der convert-Methode den Stream der
	 * Tdf-Konvertierung.
	 *
	 * @return Stream der Tdf-Konvertierung oder <code>null</code> falls er
	 *         nicht existiert
	 */
	public VKCInputStream getTdfStream() {
		if (htmlConverter != null && enableTdf) {
			return htmlConverter.getTdfStream();
		}

		return null;
	}

	/**
	 * Liefert nach dem Aufruf der convert-Methode den Stream der
	 * HTML-Konvertierung.
	 *
	 * @return Stream der HTML-Konvertierung oder <code>null</code> falls er
	 *         nicht existiert
	 */
	public VKCInputStream getHtmlStream() {
		if (zipFile != null && enableHtml) {
			incOpenStreams();

			try {
				return new VKCInputStream(new BufferedInputStream(new FileInputStream(zipFile)), zipFile.length()) {
					public void close() throws IOException {
						super.close();
						closeHtmlStream();
					}
				};
			} catch (Exception e) {
				VKCLogManager.errorLog(this, "2", "ZIP-File not found!", e);
			}
		}

		return null;
	}

	/**
	 * Liefert nach dem Aufruf der convert-Methode den Stream der
	 * PDF-Konvertierung.
	 *
	 * @return Stream der PDF-Konvertierung oder <code>null</code> falls er
	 *         nicht existiert
	 */
	public VKCInputStream getPdfStream() {
		if (pdfFile != null && enablePdf) {
			incOpenStreams();
			try {
				return new VKCInputStream(new BufferedInputStream(new FileInputStream(pdfFile)), pdfFile.length()) {
					public void close() throws IOException {
						super.close();
						closePdfStream();
					}
				};
			} catch (Exception e) {
				VKCLogManager.errorLog(this, "1", "PDF-File not found!", e);
			}
		}

		return null;
	}

	/**
	 * Gibt eine Liste zurueck, der alle HREFs einer Seite enthält.
	 *
	 * @return Link-Vektor
	 */
	public ArrayList getLinks() {
		if (htmlConverter != null) {
			return htmlConverter.getLinks();
		}

		return null;
	}

	/**
	 * Liefert den Titel des Dokuments zurück.
	 *
	 * @return Titel des Dokuments oder <code>null</code>
	 */
	public String getTitle() {
		if (htmlConverter != null) {
			return htmlConverter.getTitle();
		}

		return null;
	}

	/**
	 * Liefert eine Collection mit Objekten vom Typ TdfElement zurück, welche
	 * das Dokument beschreiben.
	 *
	 * @return Collection mit Objekten vom Typ TdfElement
	 */
	public Collection getElements() {
		if (htmlConverter != null) {
			return htmlConverter.getElements();
		}

		return null;
	}

	/**
	 * Löschen der TDF-Streams
	 */
	void closeTdfStream() {
		if (debug) {
			System.out.println("closeTdfStream");
		}

		decOpenStreams();
	}

	/**
	 * Löschen der TDF-Streams
	 */
	void closePdfStream() {
		if (debug) {
			System.out.println("closePdfStream");
		}

		decOpenStreams();
	}

	/**
	 * Löschen des Ascii-Streams
	 */
	void closeHtmlStream() {
		if (debug) {
			System.out.println("closeHtmlStream");
		}

		decOpenStreams();

		//ZIP-Datei löschen
		if (zipFile != null) {
			zipFile.delete();
		}
	}

	/**
	 * Schließt das Konverter-Objekt und fügt es wieder in den Konverter-Pool
	 * ein.
	 */
	final void closeConverter() {
		//temporäre Dateien löschen
		if (zipFile != null) {
			zipFile.delete();
		}
		//this-Referenz wieder in die Queue einfügen
	}
}