/*
 * $Id: AddAccessorAclForm.java,v 1.19 2005/09/15 13:43:58 marbobo Exp $
 * 
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 * 
 * $Log: AddAccessorAclForm.java,v $
 * Revision 1.19  2005/09/15 13:43:58  marbobo
 * + Sprachabhängige Sortierung implementiert
 *
 * Revision 1.18  2004/11/12 00:24:35  marbobo
 * + getGroupInfos() in retrieveGroupInfos() umgebannt
 *
 * Revision 1.17  2004/11/10 15:02:48  koppy
 * Projektweite Überarbeitung von Error-Logs, Stacktraces,..
 *
 * Revision 1.16  2004/08/19 14:11:06  marbobo
 * + Nur gültige Benutzer oder zukünftige gültige Benutzer anzeigen
 *
 * Revision 1.15  2004/03/11 20:17:17  bigmac
 * Anpassungen an VKCUserSerializer
 *
 * Revision 1.14  2004/03/07 13:45:45  bigmac
 * Anpassungen an VKCDocumentTypeSerializer, VKCDocumentClassSerializer, VKCDocumentStatusSerializer
 *
 * Revision 1.13  2004/02/04 15:51:52  bigmac
 * NPE bei abgelaufenen Sessions wird verhindert
 *
 * Revision 1.12  2003/12/24 10:11:55  bigmac
 * Projektweite Import-Optimierung
 *
 * Revision 1.11  2003/10/22 09:55:21  vchris
 * ACL Verwaltung mit abstraktem ACL Editor realisiert
 *
 * Revision 1.10  2003/09/26 00:20:37  marbobo
 * Sortierung der Benutzer von Nachnamen nach Benutzernamen umgestellt
 *
 * Revision 1.9  2003/09/19 15:21:08  marbobo
 * Sortierung von Benutzern und Gruppen
 *
 * Revision 1.8  2003/09/10 14:59:45  vchris
 * Umstellung auf UserInfo / GroupInfo
 *
 * Revision 1.7  2003/08/02 16:13:35  bigmac
 * *** empty log message ***
 *
 * Revision 1.6  2003/07/31 13:59:28  bigmac
 * Compilerwarnungen beseitigt
 *
 * Revision 1.5  2003/06/06 07:56:02  vchris
 * small bugfix
 *
 * Revision 1.4  2003/06/06 07:34:21  vchris
 * *** empty log message ***
 *
 * Revision 1.3  2003/05/14 12:13:29  vchris
 * Code-Kosmetik
 *
 * Revision 1.2  2003/05/08 16:10:25  vchris
 * Anpassungen bzgl. neuem ACL-Dialog
 *
 */

package vkc.view.form;

import java.sql.Timestamp;
import java.text.CollationKey;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

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

import vkc.db.entities.VKCAclType;
import vkc.db.entities.VKCUser;
import vkc.db.serializer.VKCGroupSerializer;
import vkc.db.serializer.VKCUserSerializer;
import vkc.misc.VKCLogManager;
import vkc.security.AccessorInfo;
import vkc.util.ServletUtils;
import vkc.util.VKCStringUtils;
import vkc.view.bean.GroupInfo;
import vkc.view.bean.UserInfo;

/**
 * DOCUMENT ME!
 * 
 * @author vchris
 */
public class AddAccessorAclForm extends ActionForm {
	// public static final int ACTION_CHANGE_SELECT = -1;
	public static final String PARAM_ATYPE = "AccessorType";

	private Collection accessors;
	private Collection addableUsers;
	private Collection addableGroups;

	private EditCatAclForm aclForm;	

	private int accessorType;

	private String accessorSelect = "";
	
	/**
	 * @param mapping
	 * @param request
	 */
	public void reset( ActionMapping mapping, HttpServletRequest request) {
		try {
			aclForm = (EditCatAclForm)request.getSession().getAttribute( "EditCatAclForm" );
			if ( aclForm == null ) { // Session ist abgelaufen ...
				return;
			}
		} catch ( Exception ex ) {
			VKCLogManager.errorLog( this,"1","Error getting EditCatAclForm from Session Scope",ex );
			return;
		}
		
		try {		
			addableUsers = new ArrayList();
			addableGroups = new ArrayList();
		    Timestamp t = new Timestamp( System.currentTimeMillis() );
		    List userInfos = VKCUserSerializer.retrieveUserInfos();
		    
			for ( int i = 0; i < userInfos.size(); i++ ) {
			    UserInfo u = (UserInfo)userInfos.get( i );
			    
			    //Falls Benutzer gültig oder in der nahen Zukunft gültig wird
			    if ( u.isUserValid() || 
			         u.isAccountValid() && u.getValidUntil() != null &&  u.getValidUntil().after( t ) || 
			         u.isAccountValid() && u.getValidFrom() != null && u.getValidFrom().after( t ) ) {
			        addableUsers.add( u );
			    }
			}
			
			List groupInfos = VKCGroupSerializer.retrieveGroupInfos();

			for ( int i = 0; i < groupInfos.size(); i++ ) {
			    GroupInfo g = (GroupInfo)groupInfos.get( i );
			    
			    //Falls Gruppe gültig ist oder in der nahen Zukunft gültig wird
			    if ( g.isGroupValid() || 
			         g.isAccountValid() && g.getValidUntil() != null &&  g.getValidUntil().after( t ) ||
			         g.isAccountValid() && g.getValidFrom() != null && g.getValidFrom().after( t ) ) {
			        addableGroups.add( g );
			    }
			}
		} catch ( Exception ex ) {
			VKCLogManager.errorLog( this,"1","Error retrieving Groups / Users from Database",ex );
			return;
		}
		
		// bereits vergebene Accessors aussortieren
		// zunächst schon vorhandene User herausfinden und merken
		Iterator existingUsers = aclForm.getUsers().iterator();
		ArrayList toRemoveUsers = new ArrayList();
		while ( existingUsers.hasNext() ) {
			// überprüfen, ob Eintrag schon vorhanden.
			AccessorInfo fromList = (AccessorInfo)existingUsers.next();
			Iterator it = addableUsers.iterator();
			while ( it.hasNext() ) {
				UserInfo fromAllUsers = (UserInfo)it.next();
				
				if ( fromAllUsers.getUserId().equals( fromList.getAccessorId() ) ) {
					toRemoveUsers.add( fromAllUsers );
				}
			}
		}
		
		// jetzt wirklich alle schon vorhandenen Einträge löschen;
		Iterator itRemUsers = toRemoveUsers.iterator();
		while ( itRemUsers.hasNext() ) {
		    addableUsers.remove( itRemUsers.next() );
		}
	
		// zunächst schon vorhandene Gruppen herausfinden und merken
		Iterator existingGroups = aclForm.getGroups().iterator();
		ArrayList toRemoveGroups = new ArrayList();
		while ( existingGroups.hasNext() ) {
			// überprüfen, ob Eintrag schon vorhanden.
			AccessorInfo fromList = (AccessorInfo)existingGroups.next();
			Iterator it = addableGroups.iterator();
			while ( it.hasNext() ) {
				GroupInfo fromAllGroups = (GroupInfo)it.next();
				
				if ( fromAllGroups.getGroupId().equals( fromList.getAccessorId() ) ) {
					toRemoveGroups.add(fromAllGroups);
				}
			}
		}
		
		// jetzt wirklich alle schon vorhandenen Einträge löschen;
		Iterator itRemGroups = toRemoveGroups.iterator();
		while ( itRemGroups.hasNext() ) {
		    addableGroups.remove( itRemGroups.next() );
		}
		
		String param = request.getParameter( PARAM_ATYPE );
		accessorType = -1;
		
		if ( param != null ) {
			accessorType = Integer.parseInt( param );
		}
		
		VKCUser user = ServletUtils.getUser(request);
		final Collator collator = Collator.getInstance(user.getLanguage().getLocale());

		// Collections sortieren
		Comparator userComparator = new Comparator () {
		  public int compare ( Object o1, Object o2 ) {
			UserInfo u1 = (UserInfo)o1;
			UserInfo u2 = (UserInfo)o2;
			
        	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(u1.getLastname()));
        	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(u2.getLastname()));
        	
        	return key1.compareTo(key2);
		  }
		};

		UserInfo[] users = (UserInfo[])addableUsers.toArray( new UserInfo[ 0 ] );
		Arrays.sort( users, userComparator ); 
		List uList = Arrays.asList( users );
		addableUsers.clear();
		addableUsers = uList;
		
		Comparator groupComparator = new Comparator() {
			public int compare( Object o1, Object o2 ) {
				GroupInfo g1 = (GroupInfo)o1;
				GroupInfo g2 = (GroupInfo)o2;
				
	        	CollationKey key1 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(g1.getName()));
	        	CollationKey key2 = collator.getCollationKey(VKCStringUtils.decodeXmlEntities(g2.getName()));
	        	
	        	return key1.compareTo(key2);
			}
		};

		GroupInfo[] groups = (GroupInfo[])addableGroups.toArray( new GroupInfo[ 0 ] );
		Arrays.sort( groups, groupComparator ); 
		List gList = Arrays.asList( groups );
		addableGroups.clear();
		addableGroups = gList;
		
		switch ( accessorType )	{
		 	case VKCAclType.GROUP_TYPE: accessors = addableGroups; break;
		 	case VKCAclType.USER_TYPE: accessors = addableUsers; break;
		}

		// falls keine hinzuzufügenden Accessors mehr
		if ( ( accessorType == VKCAclType.GROUP_TYPE && addableGroups.isEmpty() ) ||
			 ( accessorType == VKCAclType.USER_TYPE && addableUsers.isEmpty() ) ) {
			request.getSession().setAttribute( "vkc.acl.accessorListEmpty", "vkc.acl.noMoreAccessors" );
		} else { 
		    request.getSession().removeAttribute( "vkc.acl.accessorListEmpty" );
		}
	}

	public String getAccessorSelect() {
		return accessorSelect;
	}

	public void setAccessorSelect( String string ) {
		accessorSelect = string;
	}

	public Collection getAccessors() {
		return accessors;
	}

	public int getAccessorType() {
		return accessorType;
	}

	public void setAccessorType( int i ) {
		accessorType = i;
	}
}