/*
 * Copyright 2005-2008 Jeremy Haile, Les Hazlewood
 *
 * 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.jsecurity.authc;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsecurity.authc.event.AuthenticationEventListener;
import org.jsecurity.authc.event.mgt.AuthenticationEventListenerRegistrar;
import org.jsecurity.authc.event.mgt.AuthenticationEventManager;
import org.jsecurity.authc.event.mgt.DefaultAuthenticationEventManager;
import org.jsecurity.subject.PrincipalCollection;

import java.util.Collection;

/**
 * Superclass for almost all {@link Authenticator} implementations that performs the common work around authentication
 * attempts.
 *
 * <p>This class delegates the actual authentication attempt to subclasses but supports event propagation for
 * successful and failed logins and logouts.
 *
 * <p>In most cases, the only thing a subclass needs to do (via its {@link #doAuthenticate} implementation)
 * is perform the actual principal/credential verification process for the submitted <tt>AuthenticationToken</tt>.
 *
 * <p>This implementation employs an event-based architecture so other components may react to both failed and
 * successful authentication attempts.  Failure or success events are triggered based on the
 * subclass's {@link #doAuthenticate} implementation throwing an exception or not, respectively.  That is, a failure
 * event will be created if <tt>doAuthenticate</tt> throws an exception a success event will be created and
 * sent if it does not.  The actual events
 * themselves are constructed and sent via an {@link AuthenticationEventManager} to interested
 * {@link AuthenticationEventListener}s.  If no <tt>AuthenticationEventListener</tt>s are configured, no events will
 * be created or sent.
 *
 * <p>Both the event manager and the event listeners may be set as properties of this class, but a default event
 * manager will be provided.
 *
 * @author Jeremy Haile
 * @author Les Hazlewood
 * @since 0.1
 */
public abstract class AbstractAuthenticator
        implements Authenticator, LogoutAware, AuthenticationEventListenerRegistrar {

    /*--------------------------------------------
    |             C O N S T A N T S             |
    ============================================*/
    /**
     * Commons-logging logger
     */
    protected final transient Log log = LogFactory.getLog(getClass());

    /*--------------------------------------------
    |    I N S T A N C E   V A R I A B L E S    |
    ============================================*/
    private AuthenticationEventManager authcEventManager = new DefaultAuthenticationEventManager();

    /*--------------------------------------------
    |         C O N S T R U C T O R S           |
    ============================================*/
    public AbstractAuthenticator() {
    }

    /*--------------------------------------------
    |  A C C E S S O R S / M O D I F I E R S    |
    ============================================*/

    public AuthenticationEventManager getAuthenticationEventManager() {
        return authcEventManager;
    }

    public void setAuthenticationEventManager(AuthenticationEventManager authcEventManager) {
        this.authcEventManager = authcEventManager;
    }

    public void setAuthenticationEventListeners(Collection<AuthenticationEventListener> listeners) {
        this.authcEventManager.setAuthenticationEventListeners(listeners);
    }

    public void add(AuthenticationEventListener listener) {
        this.authcEventManager.add(listener);
    }

    public boolean remove(AuthenticationEventListener listener) {
        return this.authcEventManager.remove(listener);
    }

    /*-------------------------------------------
    |               M E T H O D S               |
    ============================================*/
    protected void sendFailureEvent(AuthenticationToken token, AuthenticationException ae) {
        this.authcEventManager.sendFailureEvent(token, ae);
    }

    protected void sendSuccessEvent(AuthenticationToken token, Account account) {
        this.authcEventManager.sendSuccessEvent(token, account);
    }

    protected void sendLogoutEvent(PrincipalCollection subjectPrincipal) {
        this.authcEventManager.sendLogoutEvent(subjectPrincipal);
    }

    public void onLogout(PrincipalCollection principals) {
        sendLogoutEvent(principals);
    }


    /**
     * Implementation of the {@link Authenticator} interface that functions in the following manner:
     *
     * <ol>
     * <li>Calls template {@link #doAuthenticate doAuthenticate} method for subclass execution of the actual
     * authentication behavior.</li>
     * <li>If an <tt>AuthenticationException</tt> is thrown during <tt>doAuthenticate</tt>, create and send a
     * failure <tt>AuthenticationEvent</tt> that represents this failure, and then propogate this exception
     * for the caller to handle.</li>
     * <li>If no exception is thrown (indicating a successful login), send a success <tt>AuthenticationEvent</tt>
     * noting the successful authentication.</li>
     * <li>Return the <tt>Account</tt></li>
     * </ol>
     *
     * @param token the submitted token representing the subject's (user's) login principals and credentials.
     * @return the Account referencing the authenticated user's account data.
     * @throws AuthenticationException if there is any problem during the authentication process - see the
     *                                 interface's JavaDoc for a more detailed explanation.
     */
    public final Account authenticate(AuthenticationToken token)
            throws AuthenticationException {

        if (token == null) {
            throw new IllegalArgumentException("Method argumet (authentication token) cannot be null.");
        }

        if (log.isTraceEnabled()) {
            log.trace("Authentication attempt received for token [" + token + "]");
        }

        Account account;
        try {
            account = doAuthenticate(token);
            if (account == null) {
                String msg = "No account information found for authentication token [" + token + "] by this " +
                        "Authenticator instance.  Please check that it is configured correctly.";
                throw new AuthenticationException(msg);
            }
        } catch (Throwable t) {
            AuthenticationException ae = null;
            if (t instanceof AuthenticationException) {
                ae = (AuthenticationException) t;
            }
            if (ae == null) {
                //Exception thrown was not an expected AuthenticationException.  Therefore it is probably a little more
                //severe or unexpected.  So, wrap in an AuthenticationException, log to warn, and propagate:
                String msg = "Authentication failed for token submission [" + token + "].  Possible unexpected " +
                        "error? (Typical or expected login exceptions should extend from AuthenticationException).";
                ae = new AuthenticationException(msg, t);
                if (log.isWarnEnabled()) {
                    log.warn(msg, t);
                }
            }
            try {
                sendFailureEvent(token, ae);
            } catch (Throwable t2) {
                String msg = "Unable to send event for failed authentication attempt - listener error?.  Please check " +
                        "your AuthenticationEventListener implementation(s).  Logging sending exception and " +
                        "propagating original AuthenticationException instead...";
                if (log.isWarnEnabled()) {
                    log.warn(msg, t2);
                }
            }


            throw ae;
        }

        if (log.isInfoEnabled()) {
            log.info("Authentication successful for token [" + token + "].  " +
                    "Returned account: [" + account + "]");
        }

        sendSuccessEvent(token, account);

        return account;
    }

    /**
     * Template design pattern hook for subclasses to implement specific authentication behavior.
     *
     * <p>Common behavior for most authentication attempts is encapsulated in the
     * {@link #authenticate} method and that method invokes this one for custom behavior.
     *
     * <p><b>N.B.</b> Subclasses <em>should</em> throw some kind of
     * <tt>AuthenticationException</tt> if there is a problem during
     * authentication instead of returning <tt>null</tt>.  A <tt>null</tt> return value indicates
     * a configuration or programming error, since <tt>AuthenticationException</tt>s should
     * indicate any expected problem (such as an unknown account or username, or invalid password, etc).
     *
     * @param token the authentication token encapsulating the user's login information.
     * @return an <tt>Account</tt> object encapsulating the user's account information
     *         important to JSecurity.
     * @throws AuthenticationException if there is a problem logging in the user.
     */
    protected abstract Account doAuthenticate(AuthenticationToken token)
            throws AuthenticationException;



}