/*
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: ExportMaintenanceAction.java,v $
 * Revision 1.6  2007/10/25 11:11:39  korowa
 * Englische Namen berichtigt
 *
 * Revision 1.5  2007/10/23 07:58:09  korowa
 * MigrationLog hinzugefügt,alle Objekte werden da rausgeschrieben, bugfixing: LastChangerId von User wird jetzt aktualisiert,
 *
 * Revision 1.4  2007/09/18 14:18:13  korowa
 * bugfixing
 *
 * Revision 1.3  2007/09/18 08:52:32  marbobo
 * + In dem Archivnamen wird wieder Kategoriename statt Kategorie-ID verwendet
 *
 * Revision 1.2  2007/09/04 12:49:08  korowa
 * bugfixing
 *
 * Revision 1.1  2007/08/28 12:15:55  korowa
 * Export- und Importfunktionen hinzugefügt
 * 
 *
 */
package vkc.administration.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.thoughtworks.xstream.XStream;

import vkc.administration.form.ExportMaintenanceForm;
import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCDocument;
import vkc.db.entities.VKCGroup;
import vkc.db.entities.VKCMigrationObjects;
import vkc.db.entities.VKCUser;
import vkc.db.serializer.VKCLanguageSerializer;
import vkc.misc.ArchiveCategory;
import vkc.misc.VKCLogManager;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.zip.*;
import vkc.util.VKCStringUtils;
import vkc.view.WebShare;
import vkc.view.bean.ResourceInfo;

public final class ExportMaintenanceAction extends SystemMaintenanceAction {
	private ActionForward INFO_FORWARD = new ActionForward(
			"/templates/${template.name}/common/InfoPage.jsp");

	public ActionForward execute(ActionMapping mapping, ActionForm f,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException {
		try {

			ExportMaintenanceForm form = (ExportMaintenanceForm) f;
			VKCUser user = form.getUser();

			if (!user.hasAdminPrivileges() && !user.getManageOwnUsers()) {
				request.setAttribute(WebShare.INFO_KEY,
						"vkc.info.access_denied");

				return INFO_FORWARD;
			}

			if (request.getParameter("action.export") != null) {
				this.handleExportAction(form, request);
				form.reset(mapping, request);
			}

			return this.handleInitializeAction(form, request);

		} catch (Exception ex) {
			throw new ServletException(ex);
		}

	}

	private void handleExportAction(ExportMaintenanceForm form,
			HttpServletRequest request) throws ServletException {
		File archivedFile = null;
		File exportObjects = null;
		VKCLogManager.migrationLog(form.getUser().getFullName(), " started Export");
		try {
			File targetDirectory = form.getArchiveDirectory();
			if (!targetDirectory.exists()) {
				targetDirectory.mkdirs();
				targetDirectory.mkdir();
			}
			form.setAllExportObjects();

			//Exportierte Objecte ins Migrationslog schreiben
			VKCLogManager.migrationLog(this,
					"Following categories will be exported:");
			Iterator iterCat = form.getExportCategories().iterator();
			while (iterCat.hasNext()) {
				VKCCategory cat = (VKCCategory) iterCat.next();
				VKCLogManager.migrationLog(cat, "name: " + cat.getName()
						+ " id: " + cat.getCategoryId());
			}

			VKCLogManager.migrationLog(this,
					"Following documents will be exported:");
			Iterator iterDoc = form.getExportDocuments().iterator();
			while (iterDoc.hasNext()) {
				VKCDocument doc = (VKCDocument) iterDoc.next();
				VKCLogManager.migrationLog(doc, "name: " + doc.getName()
						+ " id: " + doc.getDocumentId());
			}

			VKCLogManager.migrationLog(this,
					"Following groups will be exported:");
			Iterator iterGroup = form.getExportGroups().iterator();
			while (iterGroup.hasNext()) {
				VKCGroup group = (VKCGroup) iterGroup.next();
				VKCLogManager.migrationLog(group, "name: " + group.getName()
						+ " id: " + group.getGroupId());
			}

			VKCLogManager.migrationLog(this,
					"Following users will be exported:");
			Iterator iterUser = form.getExportUsers().iterator();
			while (iterUser.hasNext()) {
				VKCUser user = (VKCUser) iterUser.next();
				VKCLogManager.migrationLog(user, "name: " + user.getFullName()
						+ " id: " + user.getUserId());
			}

			VKCMigrationObjects objects = new VKCMigrationObjects();
			objects.setMigrationCategories(form.getExportCategories());
			objects.setMigrationDocuments(form.getExportDocuments());
			objects.setMigrationGroups(form.getExportGroups());
			objects.setMigrationCategoryQueries(form.getExportQueries());
			objects.setMigrationUserQueries(form.getExportUserQueries());
			objects.setMigrationUsers(form.getExportUsers());
			String dateString = new SimpleDateFormat("-yyyy-MM-dd-kk-mm-ss")
					.format(new Date());
			exportObjects = new File(targetDirectory, ArchiveCategory
					.catName2PathName(VKCStringUtils.decodeXmlEntities(form
							.getCategory().getName()))
					+ "_Export_" + dateString + ".xml");
			XStream xstream = new XStream();
			String xml = xstream.toXML(objects);
			FileOutputStream file = new FileOutputStream(exportObjects);
			file.write(xml.getBytes());

			VKCCategory cat = form.getCategory();

			ResourceInfo resource = new ResourceInfo(form.getResources(),
					VKCLanguageSerializer.getLanguage(form.getLanguageId())
							.getLocale());

			archivedFile = new ArchiveCategory().createZipFile(cat,
					targetDirectory.getAbsolutePath(), null, form
							.getRecursive(), form.getIncludeVersion(), form
							.isVirtualDocuments(), form.getUser(), resource);

			form.setFileSize(VKCStringUtils.formatBytes(archivedFile.length(),
					form.getUser().getLanguage().getLanguageId().toString()));

			// Archivierte Dokumente und Objekte nochmal zippen
			form.setExportFile(new File(form.getArchiveDirectoryPath(),
					ArchiveCategory.catName2PathName(VKCStringUtils
							.decodeXmlEntities(form.getCategory().getName()))
							+ "_Export_" + dateString + ".zip"));
			form.setExportFilePath(form.getExportFile().getCanonicalPath());

			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(form
					.getExportFile()));
			byte[] readBuffer = new byte[form.BLOCKSIZE];
			int bytesIn = 0;
			FileInputStream fis = new FileInputStream(exportObjects);
			ZipEntry anEntry = new ZipEntry("Objects.xml");
			zos.putNextEntry(anEntry);
			while ((bytesIn = fis.read(readBuffer)) != -1) {
				zos.write(readBuffer, 0, bytesIn);
			}

			FileInputStream fis2 = new FileInputStream(archivedFile);
			anEntry = new ZipEntry("ArchiveFile.7z");
			zos.putNextEntry(anEntry);
			while ((bytesIn = fis2.read(readBuffer)) != -1) {
				zos.write(readBuffer, 0, bytesIn);
			}
			fis2.close();
			fis.close();
			zos.close();
			file.close();
			request.setAttribute("succeeded", form.getResources().getMessage(
					form.getLocale(),
					"vkc.administration.systemmaintenance.export.succeded"));
			VKCLogManager.migrationLog(this, "Export completed successfully");
		} catch (IOException e) {
			VKCLogManager.errorLog(e,"",e.getMessage());
			VKCLogManager.migrationLog(this, e.getMessage());
			System.err.println(e);
			e.printStackTrace();
		} catch (Exception ex) {
			VKCLogManager.errorLog(this, "", ex.getMessage(), ex);
			VKCLogManager.migrationLog(this, ex.getMessage());
			throw new ServletException(ex);
		} finally {
			// temporäre Dateien löschen

			if (exportObjects != null)
				exportObjects.delete();
			if (archivedFile != null)
				archivedFile.delete();

		}

	}

}