/*
 * $Id: ExportMaintenanceForm.java,v 1.6 2007/11/14 12:44:22 korowa Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: ExportMaintenanceForm.java,v $
 * Revision 1.6  2007/11/14 12:44:22  korowa
 * bugfixing
 *
 * Revision 1.5  2007/11/02 19:52:19  marbobo
 * + Bugfix (Statt List werden HashSet benutzt)
 *
 * Revision 1.4  2007/10/30 14:02:54  marbobo
 * + removed unnecessary statements
 *
 * Revision 1.3  2007/10/23 07:58:09  korowa
 * MigrationLog hinzugefügt,alle Objekte werden da rausgeschrieben, bugfixing: LastChangerId von User wird jetzt aktualisiert,
 *
 * Revision 1.2  2007/10/18 09:55:53  korowa
 * Passwörter werden nur verschlüsselt exportiert, und werden bei importierten Benutzer nicht neu generiert. CreatorId für aclEntries werden gesetzt.
 *
 * Revision 1.1  2007/08/28 12:16:02  korowa
 * Export- und Importfunktionen hinzugefügt
 *
 * Revision 1.13  2005/02/20 23:34:15  marbobo
 * + Bugfix
 *
 * Revision 1.12  2004/11/10 15:02:48  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.11  2004/08/07 00:34:43  marbobo
 * + Bugfix für Zeitangaben und Refactorings
 *
 * Revision 1.10  2004/07/20 08:09:56  jonyp
 * added copyright info + cvs log
 *
 */

package vkc.administration.form;

import java.io.File;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;

import vkc.db.entities.VKCAclEntry;
import vkc.db.entities.VKCCategory;
import vkc.db.entities.VKCDocument;
import vkc.db.entities.VKCDynaAttribute;
import vkc.db.entities.VKCGroup;
import vkc.db.entities.VKCSearchQuery;
import vkc.db.entities.VKCUser;
import vkc.db.serializer.VKCCategorySerializer;
import vkc.db.serializer.VKCGroupSerializer;
import vkc.db.serializer.VKCUserRegSearchQuerySerializer;
import vkc.db.serializer.VKCUserSerializer;

import vkc.db.serializer.VKCLanguageSerializer;

import vkc.exception.DBException;

import vkc.misc.VKCLogManager;
import vkc.security.VKCAcl;
import vkc.util.VKCCategoryAbsPath;
import vkc.util.VKCStringUtils;
import vkc.view.WebShare;
import vkc.db.entities.VKCAclType;

public final class ExportMaintenanceForm extends SystemMaintenanceForm {
    public final String CONTEXT_DOCUMENTS = "Documents";
    public final String CONTEXT_CATEGORIES = "Categories";
    public final String CONTEXT_USERS = "Users";
    public final String CONTEXT_GROUPS = "Groups";
    public final String CONTEXT_END = "EndOfExport";
    public final int BLOCKSIZE = 8192;

    private boolean includeVersion = true;
    private boolean recursive = true;
    private boolean virtualDocuments = false;

    private File exportFile = null;
    private String exportFilePath = "";

    private Integer categoryId = new Integer(1);
    private Integer languageId = null;

    private String fileSize = "";

    private VKCCategory category = null;
    private List categories = null;
    private HashSet<VKCCategory> exportCategories = null;
    private HashSet<VKCUser> exportUsers = null;
    private HashSet<VKCGroup> exportGroups = null;
    private HashSet<VKCDocument> exportdocuments = null;
    private HashMap<Integer, VKCSearchQuery> exportQueries = null;
    private List<VKCSearchQuery> exportUserQueries = null;
    private Set exportGroupIds = null;
    private Set exportUserIds = null;

    public void reset(ActionMapping mapping, HttpServletRequest request) {
        super.reset(mapping, request);

        exportGroupIds = new HashSet();
        exportUserIds = new HashSet();
        exportCategories = new HashSet<VKCCategory>();
        exportUsers = new HashSet<VKCUser>();
        exportGroups = new HashSet<VKCGroup>();
        exportdocuments = new HashSet<VKCDocument>();
        exportQueries = new HashMap<Integer, VKCSearchQuery>();
        exportUserQueries = new ArrayList<VKCSearchQuery>();

        exportFile = null;

        categoryId = new Integer(1);
        fileSize = "";

        category = null;
        categories = null;

    }

    /**
     * Validiert die Eingabefelder und gibt gegebenfalls die Fehler zurück
     * 
     * @param mapping
     *            The mapping used to select this instance
     * @param request
     *            The servlet request we are processing
     */
    public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
        ActionErrors errors = new ActionErrors();

        return errors;
    }

    public void setExportFile(File file) {
        exportFile = file;
    }

    public File getExportFile() {
        if (exportFile == null && !getExportFilePath().equals("")) {
            return new File(getExportFilePath());
        }
        
        return exportFile;
    }

    public void setFileSize(String sizeStr) {
        fileSize = sizeStr;
    }

    public String getFileSize() {
        return fileSize;
    }

    public void setCategoryId(Integer id) {
        categoryId = id;
    }

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setRecursive(boolean bool) {
        recursive = bool;
    }

    public boolean getRecursive() {
        return recursive;
    }

    public void setIncludeVersion(boolean bool) {
        includeVersion = bool;
    }

    public boolean getIncludeVersion() {
        return includeVersion;
    }

    public VKCCategory getCategory() throws DBException {
        if (category == null) {
            category = VKCCategorySerializer.retrieveCategory(getCategoryId());
        }

        return category;
    }

    public String getArchiveDirectoryPath() {
        return getArchiveDirectory().getAbsolutePath();
    }

    public File getArchiveDirectory() {
        File file = null;
        String path = WebShare.getSysParameterValue("ARCHIVECATEGORY", "ArchiveCategoryPath", "");

        if (!isEmpty(path)) {
            file = new File(path);
        } else {
            file = new File(WebShare.getWebApplicationDir(), "WEB-INF/archives");
        }

        return file.getAbsoluteFile();
    }

    public boolean isVirtualDocuments() {
        return virtualDocuments;
    }

    public void setVirtualDocuments(boolean b) {
        virtualDocuments = b;
    }

    public Integer getLanguageId() {
        if (languageId == null) {
            languageId = getUser().getLanguage().getLanguageId();
        }

        return languageId;
    }

    public void setLanguageId(Integer integer) {
        languageId = integer;
    }

    public List getLanguages() {
        return VKCLanguageSerializer.getLanguages();
    }

    public String getEncodedExportFilename() throws IOException {
        String name = VKCStringUtils.filterUnicodeChars(getExportFile().getCanonicalPath());

        return VKCStringUtils.base64Encode(name);
    }

    public String getExportFilename() {
        return getExportFile().getName();
    }

    public List getCategories() {
        if (categories == null) {
            try {
                String[] queries = new String[1];
                queries[0] = "*";
                categories = VKCCategorySerializer.retrieveCategoriesForUserByQueries(null, getUser(), queries);
            } catch (DBException e) {
                VKCLogManager.errorLog(this, "1", "Can't retrieve subcategories!", e);
            }
        }
        
        return categories;
    }

    public HashMap getExportCategoryParams() {
        HashMap params = new HashMap();
        params.put("categoryId", getCategoryId());

        return params;
    }

    public String getCategoryPath() {
        VKCCategoryAbsPath cap = null;

        try {
            cap = VKCCategorySerializer.getCategoryAbsPath(getCategoryId());
        } catch (DBException e) {
        }

        if (cap == null) {
            return getResources().getMessage(getLocale(), "vkc.profile.error.homecategory");
        }

        return cap.getAbsolutePathString();
    }

    public void setAllExportObjects() {
        try {
            // alle Categorien finden
            setAllExportCategories(getCategory());
            // zu exportierende Gruppen setzen
            Iterator iter = exportCategories.iterator();
            
            while (iter.hasNext()) {
                VKCCategory exportCat = (VKCCategory) iter.next();
                VKCSearchQuery query = VKCCategorySerializer.retrieveSearchQuery(exportCat.getCategoryId());
                
                if (query != null && !query.isEmpty()) {
                    exportQueries.put(exportCat.getCategoryId(), query);
                }
                
                VKCAcl acl = exportCat.getAcl();
                List groupEntries = acl.getEntriesOfType(VKCAclType.GROUP_TYPE);
                Iterator iterGroupEntries = groupEntries.iterator();

                while (iterGroupEntries.hasNext()) {
                    VKCAclEntry entryGroup = (VKCAclEntry) iterGroupEntries.next();
                    
                    if (!exportGroupIds.contains(entryGroup.getAccessorId())) {
                        exportGroupIds.add(entryGroup.getAccessorId());
                        VKCGroup group = VKCGroupSerializer.retrieveGroup(entryGroup.getAccessorId());
                        exportGroups.add(group);
                        Set userIds = group.getGroupUserIds();
                        // alle Benutzer aus der Gruppe hinzufügen
                        Iterator iterGroupUser = userIds.iterator();
                        
                        while (iterGroupUser.hasNext()) {
                            Integer id = (Integer) iterGroupUser.next();
                            
                            if (!exportUserIds.contains(id)) {
                                exportUserIds.add(id);
                                VKCUser groupUser = VKCUserSerializer.retrieveUser(id);
                                groupUser.setClearPassword("");
                                HashMap queries = VKCUserRegSearchQuerySerializer.retrieveSearchQueries(groupUser.getUserId());
                                
                                if (queries != null && !queries.isEmpty() && queries.values().size() > 0) {
                                    // exportQueries.addAll(queries.values());
                                    Iterator iterQuery = queries.values().iterator();
                                    
                                    while (iterQuery.hasNext()) {
                                        query = (VKCSearchQuery) iterQuery.next();
                                        query.setUserId(groupUser.getUserId());
                                        
                                        if (!query.isEmpty() && !exportUserQueries.contains(query)) {
                                            exportUserQueries.add(query);
                                        }
                                    }

                                }
                                
                                exportUsers.add(groupUser);
                            }
                        }
                    }
                }

                // alle Benutzer, die explizit Zugriff auf Kategorie haben,
                // sammeln

                List userEntries = acl.getEntriesOfType(VKCAclType.USER_TYPE);
                Iterator iterUser = userEntries.iterator();

                while (iterUser.hasNext()) {
                    VKCAclEntry userEntry = (VKCAclEntry) iterUser.next();
                    Integer id = userEntry.getAccessorId();
                    
                    if (!exportUserIds.contains(id)) {
                        exportUserIds.add(id);
                        VKCUser groupUser = VKCUserSerializer.retrieveUser(id);
                        HashMap queries = VKCUserRegSearchQuerySerializer.retrieveSearchQueries(groupUser.getUserId());
                        
                        if (queries != null && !queries.isEmpty() && queries.values().size() > 0) {
                            // exportQueries.addAll(queries.values());
                            Iterator iterQuery = queries.values().iterator();
                            
                            while (iterQuery.hasNext()) {
                                query = (VKCSearchQuery) iterQuery.next();
                                query.setUserId(groupUser.getUserId());
                                
                                if (!query.isEmpty() && !exportUserQueries.contains(query)) {
                                    exportUserQueries.add(query);
                                }
                            }
                        }
                        
                        groupUser.setClearPassword("");
                        exportUsers.add(groupUser);
                    }
                }
            }
            // alle Documente sammeln
            setAllExportDocuments();
        } catch (DBException e1) {
            VKCLogManager.errorLog(this, "1", "Can't retrieve groups and users!", e1);
            e1.printStackTrace();
        }
    }

    private void setAllExportCategories(VKCCategory exportCategory) {
        // zu exportierende Categories sammeln
        if (!exportCategories.contains(exportCategory)) {
            exportCategories.add(exportCategory);
        }

        Set exportCat = exportCategory.getSubCategoriesIds();
        
        if (exportCat != null && exportCat.size() > 0) {
            Iterator iter = exportCat.iterator();
            
            while (iter.hasNext()) {
                VKCCategory expCat;
                
                try {
                    expCat = VKCCategorySerializer.retrieveCategory((Integer) iter.next());
                    setAllExportCategories(expCat);
                } catch (DBException e) {
                    VKCLogManager.errorLog(this, "1", "Can't retrieve exportcategory!", e);
                }

            }
        }

    }

    private void setAllExportDocuments() {
        // zu exportierende Categories sammeln
        Iterator iterCat = exportCategories.iterator();
        
        while (iterCat.hasNext()) {
            VKCCategory exportCategory = (VKCCategory) iterCat.next();
            List documents = exportCategory.getDocuments();
            
            if (documents != null && documents.size() > 0) {
                Iterator iter = documents.iterator();
                
                while (iter.hasNext()) {
                    VKCDocument expDoc = (VKCDocument) iter.next();
                    
                    try {
                        if (expDoc.getVersionNo().intValue() > 1) {
                            Collection allVersions = expDoc.getAllVersions();
                            Iterator iterVersions = allVersions.iterator();
                            
                            while (iterVersions.hasNext()) {
                                VKCDocument expDocVers = (VKCDocument) iterVersions.next();
                                // Da bei älteren versionen eines Dokumentes keine KategorieId gemerkt wird
                                //die Information als Dynamisches Attribute speichern
                                VKCDynaAttribute version = new VKCDynaAttribute();
                                version.setName("CategoryId");
                                version.setValue(expDoc.getCategoryId().toString());
                                expDocVers.getDynaAttributes().add(version);
                                //wenn Publisher nicht exportiert wird 
                                
                                if (!exportUserIds.contains(expDocVers.getPublisherId())) {
                                    VKCUser publisher = VKCUserSerializer.retrieveUser(expDocVers.getPublisherId());
                                    exportUsers.add(publisher);
                                    exportUserIds.add(publisher.getUserId());
                                }
                                
                                if (!exportdocuments.contains(expDocVers)) {
                                    exportdocuments.add(expDocVers);
                                }
                            }
                        } else {
                            //wenn Publisher nicht exportiert wird 
                            if (!exportUserIds.contains(expDoc.getPublisherId())) {
                                VKCUser publisher = VKCUserSerializer.retrieveUser(expDoc.getPublisherId());
                                exportUsers.add(publisher);
                                exportUserIds.add(publisher.getUserId());
                            }
                            
                            if (!exportdocuments.contains(expDoc)) {
                                exportdocuments.add(expDoc);
                            }
                        }
                    } catch (DBException e) {
                        VKCLogManager.errorLog(this, "1", "Can't retrieve documents!", e);
                    }
                }
            }
        }
    }

    public HashSet getExportCategories() {
        return exportCategories;
    }

    public HashSet getExportGroups() {
        return exportGroups;
    }

    public HashSet getExportUsers() {
        return exportUsers;
    }

    public HashSet getExportDocuments() {
        return exportdocuments;
    }

    public void setExportdocuments(HashSet exportdocuments) {
        this.exportdocuments = exportdocuments;
    }

    public String getExportFilePath() {
        return exportFilePath;
    }

    public void setExportFilePath(String exportFilePath) {
        this.exportFilePath = exportFilePath;
    }

    public HashMap<Integer, VKCSearchQuery> getExportQueries() {
        return exportQueries;
    }

    public void setExportQueries(HashMap<Integer, VKCSearchQuery> exportQueries) {
        this.exportQueries = exportQueries;
    }

    public List<VKCSearchQuery> getExportUserQueries() {
        return exportUserQueries;
    }

    public void setExportUserQueries(List<VKCSearchQuery> exportUserQueries) {
        this.exportUserQueries = exportUserQueries;
    }
}