/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
package gov.va.med.fw.security;

import javax.security.auth.Subject;
import javax.security.auth.login.AccountExpiredException;
import javax.security.auth.login.CredentialExpiredException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;

import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.service.ServiceException;
import gov.va.med.fw.ui.security.ChangePasswordInfo;

/**
 * Security Service defines user authentication related operations.
 * 
 * @author Ghazenfer Mansoor
 */
public interface SecurityService {

    /**
     * Authenticate the user given username and password. This method must throw
     * LoginException if authentication is not successful for any reason.
     * Different LoginExcpetion's should be thrown depending upon the type of
     * failure occurs. 
     * If there are consecutive failure occurs, this method also
     * lock the user account.
     * 
     * @param username
     * @param password
     * @return <code>javax.security.auth.Subject</code>.
     * @throws FailedLoginException
     *             if user does not exists or bad username/password combination.
     * @throws AccountLockedException
     *             if the user account is locked.
     * @throws AccountExpiredException
     *             if the user account is expired.
     * @throws CredentialExpiredException
     *             if the user password is expired.
     * @throws AccountDisabledException
     *             if the user account is disabled.
     * @throws LoginException
     *             if there is an other error authenticating the user.
     */
    public Subject authenticate(String username, char[] password)
        throws LoginException;
    
    /**
     * Requires and optional security code for validation
     * @param username
     * @param password
     * @param securityCode
     * @return
     * @throws LoginException
     */
    public void verifySecurityCode(String username, String securityCode)
        throws LoginException;    
    /**
     * Helper method to find the UserPrincipal given the user identifier.
     * This method returns null if there is no user existing with this identifier.
     * 
     * @param userId
     * @return UserPrincipal if user is found or null otherwise.
     * @throws ServiceException if there is any error finding the user.
     */
    public UserPrincipal getUserById(EntityKey userId) throws ServiceException;

    /**
     * Lock the user account given the user identifier.
     * 
     * @param userId
     * @throws ServiceException if there is any error.
     */
    public void lockAccount(EntityKey userId) throws ServiceException;

    /**
     * Unlock the user account given the user Identifier.
     * 
     * @param userId
     * @throws ServiceException if there is any error.
     */
    public void unlockAccount(EntityKey userId) throws ServiceException;

    /**
     * Enable the user account given the user Identifier.
     * 
     * @param userId
     * @throws ServiceException if there is any error.
     */
    public void enableAccount(EntityKey userId) throws ServiceException;

    /**
     * Disable the user account given the user Identifier.
     * 
     * @param userId
     * @throws ServiceException if there is any error.
     */
    public void disableAccount(EntityKey userId) throws ServiceException;
    
    /**
     * Change user password.
     * 
     * @param changePasswordInfo
     * @throws ServiceException if there is any error.
     */
    public void changePassword(ChangePasswordInfo changePasswordInfo) throws LoginException, ServiceException;

    /**
     * Reset the user password by the given password.
     * @param username
     * @param password
     * @throws ServiceException if there is any error
     */
    public void resetPassword(String username, String password) throws ServiceException;
}