/*
 * AudiLoginModule.java
 * $Revision:$
 *
 * Copyright (c) 2006 Good Technology Ltd.
 */


package test;

import java.security.Principal;
import java.sql.SQLException;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
import com.sun.identity.authentication.spi.AMLoginModule;
import com.sun.identity.authentication.spi.AuthLoginException;
import com.sun.identity.authentication.util.ISAuthConstants;
import com.sun.identity.shared.datastruct.CollectionHelper;
import com.sun.identity.shared.debug.Debug;


public class TestLoginModule extends AMLoginModule {

	private static String AUTHLEVEL = "sunAMAuthDataStoreAuthLevel";

	private static final String amAuthTest = "amAuthTest";
	private IdDAO dao;
	private Debug debug = Debug.getInstance(amAuthTest);

	private TestPrincipal userPrincipal = null;
	private Long validatedUserID = null;
	private Map sharedState;
	private String emailAddress;

	public Principal getPrincipal() {
		if (userPrincipal != null) {
			return userPrincipal;
		}
		if (validatedUserID != null) {
			userPrincipal = new TestPrincipal(validatedUserID.longValue());
		}
		return userPrincipal;
	}

	public void init(Subject subject, Map sharedState, Map options) {
		dao = IdDAO.getInstance();
		String authLevel = CollectionHelper.getMapAttr(options, AUTHLEVEL);
		if (authLevel != null) {
			try {
				setAuthLevel(Integer.parseInt(authLevel));
			} catch (Exception e) {
				debug.error("Unable to set auth level " + authLevel,e);
			}
		}
		this.sharedState = sharedState;
	}

	public int process(Callback[] callbacks, int state)
		throws LoginException
	{
		int currentState = state;
		int retVal = 0;
		Callback[] idCallbacks = new Callback[2];
		try {

			if (currentState == ISAuthConstants.LOGIN_START) {
				String userPassword = null;
				if (callbacks !=null) {
					if (callbacks.length == 0) {
						emailAddress = (String) sharedState.get(getUserKey());
						userPassword = (String) sharedState.get(getPwdKey());
						if (emailAddress == null || userPassword == null) {
							return ISAuthConstants.LOGIN_START;
						}
						NameCallback nameCallback = new NameCallback("dummy");
						nameCallback.setName(emailAddress);
						idCallbacks[0] = nameCallback;
						PasswordCallback passwordCallback = new PasswordCallback
						("dummy",false);
						passwordCallback.setPassword(userPassword.toCharArray());
						idCallbacks[1] = passwordCallback;
					} else {
						idCallbacks = callbacks;
						emailAddress = ( (NameCallback) callbacks[0]).getName();
						userPassword = String.valueOf(((PasswordCallback)
								callbacks[1]).getPassword());
					}
				}
				//store username password both in success and failure case
				storeUsernamePasswd(emailAddress, userPassword);

				User user = dao.loadUserByEmail(emailAddress);
				if (user != null) {
					retVal=ISAuthConstants.LOGIN_SUCCEED;
					validatedUserID = new Long(user.getId());
				} else {
					throw new AuthLoginException(amAuthTest, "authFailed",
							null);
				}
			}  else {
				setFailureID(emailAddress);
				throw new AuthLoginException(amAuthTest, "authFailed",
						null);
			}
		} catch (SQLException ex) {
			debug.message("idRepo Exception");
			setFailureID(emailAddress);
			throw new AuthLoginException(amAuthTest, "authFailed",
					null, ex);
		}
		return retVal;
	}
}
