package org.inria.bmajwatcher.client.services;

import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

/**
 * Service for CRUD operation on users and groups.
 * 
 * @author rsabas
 *
 */
@RemoteServiceRelativePath("userManagerService")
public interface UserManagerService extends RemoteService {
	
	/**
	 * Adds a new user to db and creates groups if they don't exist.
	 * User password is generated and sent by mail.
	 * 
	 * @param login user login
	 * @param groups groups users belongs to
	 * @param authType authentication type (LDAP or local)
	 * @param mail user mail
	 * 
	 * @return whether operation succeeded
	 */
	public boolean addUser(String login, Set<String> groups, String authType, String mail);
	
	/**
	 * Sets user password.
	 * Only works for non ldap authentication.
	 * 
	 * @param login user login
	 * @param password new password. If null, password will be generated
	 * 
	 * @return whether operation succeeded
	 */
	public boolean setUserPassword(String login, String password);
	
	/**
	 * Sets new mail address for given user.
	 * @param login
	 * @param newMail
	 * @return
	 */
	public boolean setUserMail(String login, String newMail);
	
	/**
	 * Adds user to a group. If group doesn't exist, it is created.
	 * 
	 * @param login user login
	 * @param group group name
	 * 
	 * @return whether operation succeeded
	 */
	public boolean addUserToGroup(String login, String group);
	
	/**
	 * Removes user from given group.
	 * A user should always belong to a group.
	 * If this group was the only one that user belonged to,
	 * a new group will be generated for the user.
	 *  
	 * @param login user login
	 * @param group group user is to be removed from
	 * 
	 * @return whether operation succeeded
	 */
	public boolean removeUserFromGroup(String login, String group);
	
	/**
	 * Deletes user.
	 * 
	 * @param login user login to delete
	 * @return whether operation succeeded
	 */
	public boolean deleteUser(String login);
	
	/**
	 * Adds a group.
	 * @param groupName group name
	 * 
	 * @return whether operation succeeded
	 */
	public boolean addGroup(String groupName);
	
	/**
	 * Sets new group name.
	 * 
	 * @param oldName group to be renamed
	 * @param newName new group name
	 * 
	 * @return whether operation succeeded
	 */
	public boolean updateGroup(String oldName, String newName);
	
	/**
	 * Removes a group.
	 * Do not delete related users.
	 * As users always belong to a group, generates a new group for each user.
	 * 
	 * @param groupName group name
	 * @return whether operation succeeded
	 */
	public boolean deleteGroup(String groupName);
	
	/**
	 * Returns user list as a map that contain
	 * - user login
	 * - user groups separated by _:_
	 * - user auth type
	 * 
	 * Key is user login.
	 * 
	 * @return
	 */
	public Map<String, Map<String, String>> getUsers();
	
	/**
	 * Returns a list of user logins.
	 * 
	 * @return
	 */
	public List<String> getLogins();
	
	/**
	 * Set owner for given bank to new given owner.
	 * 
	 * @param newOwnerLogin
	 * @return
	 */
	public boolean changeBankOwner(String bankName, String newOwnerLogin);
	
	/**
	 * Returns group list.
	 * 
	 * @return
	 */
	public List<String> getGroups();
	
	/**
	 * Returns administrator login.
	 * @return
	 */
	public String getAdminLogin();
	
	/**
	 * Generates a new key for given user.
	 * 
	 * @param user login to reset key
	 * @return success ?
	 */
	public boolean resetUID(String login);
	
	/**
	 * Returns key for given user.
	 * 
	 * @param login
	 * @return
	 */
	public String getUserKey(String login);
	
	/**
	 * Returns user login from its auth key.
	 * 
	 * @param key
	 * @return
	 */
	public String getUserLoginFromKey(String key);
	
	/**
	 * If bank is public, set visibility to private and vice versa
	 * 
	 * @param bank
	 * @param visibility new access mode. true=public, false=private
	 * @return success?
	 */
	public boolean changeBankVisibility(String bank, boolean visibility);
	
}
