package org.sagebionetworks.repo.manager;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.sagebionetworks.authutil.AuthUtilConstants;
import org.sagebionetworks.repo.model.AuthorizationConstants;
import org.sagebionetworks.repo.model.DatastoreException;
import org.sagebionetworks.repo.model.GroupMembershipDAO;
import org.sagebionetworks.repo.model.GroupPermissionsDAO;
import org.sagebionetworks.repo.model.InvalidModelException;
import org.sagebionetworks.repo.model.User;
import org.sagebionetworks.repo.model.UserDAO;
import org.sagebionetworks.repo.model.UserGroup;
import org.sagebionetworks.repo.model.UserInfo;
import org.sagebionetworks.repo.web.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;

public class UserGroupManagerImpl implements UserGroupManager {
	@Autowired
	UserDAO userDAO;
	
	@Autowired
	GroupMembershipDAO groupMembershipDAO;
	
	@Autowired
	GroupPermissionsDAO groupPermissionsDAO;
	
	// for testing
	public void setUserDAO(UserDAO userDAO) {this.userDAO=userDAO;}
	public void setGroupMembershipDAO(GroupMembershipDAO groupMembershipDAO) {this.groupMembershipDAO=groupMembershipDAO;}

	
	/**
	 *
	 * NOTE:  This method has the side effect of creating in the 'permissions' representation
	 * of groups any groups that the GroupMembershipDAO knows the user to belong to.  That is,
	 * the 'truth' about groups is assumed to be in the system managing 'group memberships'
	 * and is mirrored in the system managing group permissions.
	 */
	public UserInfo getUserInfo(String userName) throws DatastoreException, NotFoundException {
		UserInfo userInfo = new UserInfo();
		User user = null;
		if (AuthUtilConstants.ANONYMOUS_USER_ID.equals(userName)) {
			user = new User();
			user.setUserId(AuthUtilConstants.ANONYMOUS_USER_ID);
		} else {
			user = userDAO.getUser(userName);
			if (user==null) throw new NullPointerException("No user named "+userName+". Users: "+userDAO.getAll());
		}
		userInfo.setUser(user);
		Collection<String> groupNames = groupMembershipDAO.getUserGroupNames(userName);
		Map<String, UserGroup> existingGroups = groupPermissionsDAO.getGroupsByNames(groupNames);
		Set<UserGroup> groups = new HashSet<UserGroup>();
		for (String groupName : groupNames) {
			UserGroup group = existingGroups.get(groupName);
			if (group!=null) {
				groups.add(group);
			} else {
				// the group needs to be created
				// possibly set other fields
				if (groupName.equals(AuthorizationConstants.ADMIN_GROUP_NAME)) {
					throw new IllegalStateException("Admin group should exist in the system.");
				} else {
					group = new UserGroup();
					group.setName(groupName);
					try {
						String id = groupPermissionsDAO.create(group);
						group.setId(id);
					} catch (InvalidModelException ime) {
						// should not happen if our code is written correctly
						throw new RuntimeException(ime);
					}
					groups.add(group);
				}
			}
		}
		UserGroup individualGroup = groupPermissionsDAO.getIndividualGroup(userName);
		if (individualGroup==null) {
			individualGroup = groupPermissionsDAO.createIndividualGroup(userName);
		}
		userInfo.setIndividualGroup(individualGroup);
	userInfo.setGroups(groups);
		return userInfo;
	}	
	

	

}

@@ -2116,16 +2116,154 @@
 pNames =
+ null;%0D%0A%09%09if (AuthUtilConstants.ANONYMOUS_USER_ID.equals(userName)) %7B%0D%0A%09%09%09groupNames = new HashSet%3CString%3E();%0D%0A%09%09%7D else %7B%0D%0A%09%09%09groupNames =
  groupMe
@@ -2304,16 +2304,21 @@
 Name);%0D%0A
+%09%09%7D%0D%0A
 %09%09Map%3CSt
@@ -3196,16 +3196,81 @@
 %7D%0D%0A%09%09%7D%0D%0A
+%09%09if (!AuthUtilConstants.ANONYMOUS_USER_ID.equals(userName)) %7B%0D%0A%09
 %09%09UserGr
@@ -3342,16 +3342,17 @@
 Name);%0D%0A
+%09
 %09%09if (in
@@ -3378,16 +3378,17 @@
 ) %7B%0D%0A%09%09%09
+%09
 individu
@@ -3447,31 +3447,33 @@
 userName);%0D%0A
+%09
 %09%09%7D%0D%0A%09%09
+%09
 userInfo.set
@@ -3507,16 +3507,75 @@
 roup);%0D%0A
+%09%09%7D%0D%0A%09%09groups.add(groupPermissionsDAO.getPublicGroup());%0D%0A%09
 %09userInf

fix for broken build...