/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/tamino/testsuite/junit/urm/org/apache/slide/urm/test/authenticator/userdb/threads/TestThreadAddUserToGroup.java,v 1.3 2004/07/30 06:52:21 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:52:21 $
 *
 * ====================================================================
 *
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.slide.urm.test.authenticator.userdb.threads;

import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import org.apache.slide.urm.URMException;
import org.apache.slide.urm.authenticator.URMAdministrator;
import org.apache.slide.urm.authenticator.URMAuthenticator;
import org.apache.slide.urm.authenticator.URMSubject;
import org.apache.slide.urm.authenticator.userdb.URMGroup;
import org.apache.slide.urm.authenticator.userdb.URMUser;
import org.apache.slide.urm.authenticator.userdb.impl.URMGroupImpl;
import org.apache.slide.urm.authenticator.userdb.impl.URMUserImpl;

/**
 * @author zsa
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class TestThreadAddUserToGroup extends TestThreadUserDbBase {
    
    private List      mUsers  = null;
    private List      mGroups = null;
    private Hashtable mCreatedGroupToUsersLinks = new Hashtable();
    private boolean   mIsRandom = false;

    public TestThreadAddUserToGroup(URMAuthenticator auth, URMAdministrator admin, String domain, List users, List groups, boolean isRandom) {
        super(auth, admin, domain);
        mUsers = users;
        mGroups = groups;
        mIsRandom = isRandom;
    }
    
    public void create() {
//        try {
        for (Iterator giter = mGroups.iterator(); giter.hasNext();) {
            URMGroup urm_grp = null;
            String grpname = (String)giter.next();
            try {
                urm_grp = mAdministrator.getGroup(grpname, mDomain);
            } catch (URMException e) {
                urm_grp = null; //e.printStackTrace();
            }
            if (urm_grp == null) {
                System.out.println("\ngetGroup('"+grpname+"') failed.");
                break;
            }
            List addedusrs = new LinkedList();
            if (mIsRandom) {
                int num = mRandom.nextInt(mUsers.size());
                for (int i = 0; i < num; ++i) {
                    String usrname = (String)mUsers.get(mRandom.nextInt(mUsers.size()));
                    if (addedusrs.contains(usrname))
                        continue;
                    try {
                        urm_grp.addUserToGroup(usrname, mDomain);
                    } catch (URMException e) {
                        System.out.println("\naddUserToGroup('"+usrname+"', '"+grpname+"') failed.");
                        break; //e1.printStackTrace();
                    }
                    addedusrs.add(usrname);
                }
            }
            else {
                for (Iterator uiter = mUsers.iterator(); uiter.hasNext();) {
                    String usrname = (String)uiter.next();
                    try {
                        urm_grp.addUserToGroup(usrname, mDomain);
                    } catch (URMException e) {
                        System.out.println("\naddUserToGroup('"+usrname+"', '"+grpname+"') failed.");
                        break; //e1.printStackTrace();
                    }
                    addedusrs.add(usrname);
                }
            }
            mCreatedGroupToUsersLinks.put(grpname, addedusrs);
        }
/*        } catch (Throwable e) {
            e.printStackTrace();
            mThrowable = e;
        } finally {
            if (mThrowable != null) {
                clear();
            }
        }*/
    }
    
    public void update() {
        try {
        Vector reserved_usrnames = new Vector();
        Vector reserved_grpnames = new Vector();
        int i = 0;
        // TODO
        for (Iterator giter = mGroups.iterator(); giter.hasNext();) {
            String usrname = null;
            URMGroup urm_grp = mAdministrator.getGroup((String)giter.next(), mDomain);
            String grpname = urm_grp.getName();
            for (Iterator iter = urm_grp.getGroupMembers().iterator(); iter.hasNext();) {
                if (reserved_usrnames.contains((usrname = ((URMSubject)iter.next()).getName())))
                    usrname = null;
                else
                    break;
            }
            if (usrname == null)
                continue;
            ++i;
            switch (i % 5) {
            case 0:
                // 0. remove one/two user from a group
                urm_grp.removeUserFromGroup(usrname, mDomain);
                ((List)mCreatedGroupToUsersLinks.get(grpname)).remove(usrname);
                break;
            case 1:
                // 1. leave just one users in a group
                break;
            case 2:
                // 2. remove all users of a group
                for (Iterator iter = urm_grp.getGroupMembers().iterator(); iter.hasNext();) {
                    String un = ((URMSubject)iter.next()).getName();
                    urm_grp.removeUserFromGroup(un, mDomain);
                    ((List)mCreatedGroupToUsersLinks.get(grpname)).remove(un);
                }
                break;
            case 3: {
                // 3. remove elements to make a user that has only one groups
                URMUser urm_usr = mAdministrator.getUser(usrname, mDomain);
                Iterator iter = urm_usr.getGroups().iterator();
                if (iter.hasNext()) iter.next();
                while (iter.hasNext()) {
                    String gn = ((URMSubject)iter.next()).getName();
                    mAdministrator.getGroup(gn, mDomain).removeUserFromGroup(usrname, mDomain);
                    ((List)mCreatedGroupToUsersLinks.get(gn)).remove(usrname);
                }
                reserved_usrnames.add(usrname);
                } break;
            case 4: {
                // 4. remove elements to make a user that has NO groups
                URMUser urm_usr = mAdministrator.getUser(usrname, mDomain);
                for (Iterator iter = urm_usr.getGroups().iterator(); iter.hasNext();) {
                    String gn = ((URMSubject)iter.next()).getName();
                    mAdministrator.getGroup(gn, mDomain).removeUserFromGroup(usrname, mDomain);
                    ((List)mCreatedGroupToUsersLinks.get(gn)).remove(usrname);
                }
                } break;
            }
        }
        } catch (Throwable e) {
            e.printStackTrace();
            mThrowable = e;
        }
    }

    public void check() {
        try {
            // check group members
            Hashtable created_user_groups_links = new Hashtable();
            for (Iterator giter = mGroups.iterator(); giter.hasNext();) {
                URMGroup urm_grp = mAdministrator.getGroup((String)giter.next(), mDomain);
                String gname = urm_grp.getName();
                Set gusrs = (Set)urm_grp.getGroupMembers();
                Collection susrs = (List)mCreatedGroupToUsersLinks.get(gname);
                if ( (susrs == null && (gusrs == null || gusrs.size() == 0)) ||
                     (gusrs == null && (susrs == null || susrs.size() == 0)))
                    continue;
                if (gusrs.size() != susrs.size())
                    System.out.println("\nThe size of the retrieved users of '"+gname+"' is "
                            +gusrs.size()+" but the added users was " +susrs.size()+ " (it was added in create()).");
                for (Iterator suiter = susrs.iterator(); suiter.hasNext();) {
                    String uname = (String)suiter.next();
                    if (!created_user_groups_links.containsKey(uname))
                        created_user_groups_links.put(uname, new LinkedList());
                    ((List)created_user_groups_links.get(uname)).add(gname);
                    if (!URMUserImpl.contains(gusrs, uname, mDomain))
                        System.out.println("\nThe '"+uname+"' user cannot be found among the members of '"
                                                +gname+"' group (it was added in create()).");
                }
            }
            // check groups of a user
            for (Iterator uiter = mUsers.iterator(); uiter.hasNext();) {
                URMUser urm_usr = mAdministrator.getUser((String)uiter.next(), mDomain);
                String uname = urm_usr.getName();
                Set ggrps = (Set)urm_usr.getGroups();
                Collection sgrps = (List)created_user_groups_links.get(uname);
                if ( (sgrps == null && (ggrps == null || ggrps.size() == 0)) ||
                     (ggrps == null && (sgrps == null || sgrps.size() == 0)))
                    continue;
                if (ggrps.size() != sgrps.size())
                    System.out.println("\nThe size of the retrieved groups of '"+uname+"' is "
                            +ggrps.size()+" but the added groups was " +sgrps.size()+ " (it was added in create()).");
                for (Iterator sgiter = sgrps.iterator(); sgiter.hasNext();) {
                    String gname = (String)sgiter.next();
                    if (!URMGroupImpl.contains(ggrps, gname, mDomain))
                        System.out.println("\nThe '"+gname+"' group cannot be found among the groups of '"
                                                +uname+"' user (it was added in create()).");
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
            mThrowable = e;
        }
    }
    
    public void clear() {
        // TODO remove using mCreatedGroupToUsersLinks to remove the members
        //      and then check if remains something there
        for (Iterator giter = mGroups.iterator(); giter.hasNext();) {
            try {
                URMGroup urm_grp = mAdministrator.getGroup((String)giter.next(), mDomain);
                String gname = urm_grp.getName();
                Collection gusrs = (Set)urm_grp.getGroupMembers();
                for (Iterator guiter = gusrs.iterator(); guiter.hasNext();) {
                    String uname = ((URMSubject)guiter.next()).getName();
                    urm_grp.removeUserFromGroup(uname, mDomain);
                }
                if (urm_grp.getGroupMembers().size() > 0)
                    System.out.println("\nAfter removing all the users from the '"+gname+
                            "' group it still contains one (it was added in create()).");
                
            } catch (Throwable e) {
                e.printStackTrace();
                mThrowable = e;
            }
        }
    }

}
