//----------------------------BEGIN LICENSE----------------------------
/* 
 * Willow : the Open Source WorkFlow Project
 * Distributable under GNU LGPL license by gun.org
 *
 * Copyright (C) 2004-2010  huihoo.org 
 * Copyright (C) 2004-2010  ZosaTapo <dertyang@hotmail.com> 
 * 
 * ====================================================================
 * Project Homepage : http://www.huihoo.org/willow
 * Source Forge     : http://sourceforge.net/projects/huihoo
 * Mailing list     : willow@lists.sourceforge.net 
 */
//----------------------------END  LICENSE-----------------------------
package org.huihoo.willow.realm;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.huihoo.willow.LifecycleException;
import org.huihoo.willow.Logger;
import org.huihoo.workflow.desktop.UserDatabase;
import org.huihoo.workflow.usermodel.WorkflowParticipant;

import org.huihoo.commons.jdbc.Store;

public class UserDatabaseRealm extends RealmBase
{
	protected static Log log = LogFactory.getLog(UserDatabaseRealm.class);

	/**
	 * Descriptive information about this RealmDatabase implementation.
	 */
	protected static final String info = "UserDatabaseRealm/1.0";

	/**
	 * Descriptive information about this RealmDabtase implementation.
	 */
	protected static final String name = "UserDatabaseRealm";

	//----------------------------------------------------- Instance Variables
	protected UserDatabase userDatabase;
	protected Store realm_store;

	//------------------------------------------------------------------------------------
	// Store utilities
	//------------------------------------------------------------------------------------ 
	public Store getStore()
	{
		return this.realm_store;
	}

	public void setStore(Store store)
	{
		this.realm_store = store;
	}

	/**
	 * Return descriptive information about this Realm implementation and
	 * the corresponding version number, in the format
	 * <code>&lt;description&gt;/&lt;version&gt;</code>.
	 */
	public String getInfo()
	{
		return info;
	}

	// --------------------------------------------------------- Public Methods
	public WorkflowParticipant authenticate(String username, String credentials)
	{
//		// Does a user with this username exist?
//		WorkflowParticipant user = userDatabase.findParticipant(username);
//		if (user == null)
//		{
//			return (null);
//		}
//		// Do the credentials specified by the user match?
//		// FIXME - Update all realms to support encoded passwords
//		boolean validated = false;
//		validated = credentials.equals(user.getPassword());
//		if (!validated)
//		{
//			if (debug >= 2)
//			{
//				log(sm.getString("userDatabaseRealm.authenticateFailure", username));
//				return (null);
//			}
//		}
//		// Construct a GenericPrincipal that represents this user
//		if (debug >= 2)
//		{
//			log(sm.getString("userDatabaseRealm.authenticateSuccess", username));
//		}
		
//		return user;

		return null;
		
	}

	// ------------------------------------------------------ Protected Methods

	/**
	 * Return a short name for this Realm implementation.
	 */
	protected String getName()
	{

		return (this.name);

	}

	/**
	 * Return the password associated with the given principal's user name.
	 */
	protected String getPassword(String username)
	{

		return (null);

	}

	/**
	 * Return the Participant associated with the given user name.
	 */
	protected WorkflowParticipant getParticipant(String username)
	{

		return (null);

	}

	//------------------------------------------------------ Lifecycle Methods
	/**
	 * Prepare for the beginning of active use of the public methods of this
	 * component.  This method should be called before any of the public
	 * methods of this component are utilized.  It should also send a
	 * LifecycleEvent of type START_EVENT to any registered listeners.
	 *
	 * @exception LifecycleException if this component detects a fatal error
	 *  that prevents this component from being used
	 */
	public void start() throws LifecycleException
	{
		// Validate and update our current component state
		if (started)
		{
			log.info(sm.getString("userdatabaseRealm.alreadyStarted"));
			return;
		}
		lifecycle.fireLifecycleEvent(START_EVENT, null);
		started = true;
		Throwable throwable = null;

//		SPIUserDatabase gudb = DatabaseRegistry.getUserDatabase(DatabaseRegistry.WILLOW_DRIVER_CLASS);
//		if (gudb != null)
//		{
//			try
//			{
//				SPIUserDatabase udbImpl = (SPIUserDatabase) gudb.clone();
//				
//				userDatabase = new CoreUserDatabaseImpl(udbImpl);
//				
//				SchemaContext schemaContext = StoreContext.getInstance().getSchemaContext();
//				userDatabase.setSchemaContext(schemaContext);
//
//				if (this.realm_store == null)
//				{
//					this.realm_store = StoreContext.getInstance().getStore(org.huihoo.workflow.Constants.USERDATABASE_STORE_KEY);
//					log.info(sm.getString("userDatabaseRealm.defaultStore", this.realm_store));
//				}
//				userDatabase.setStore(this.realm_store);
//			}
//			catch (Throwable ex)
//			{
//				throwable = ex;
//				userDatabase = null;
//			}
//		}
		// Create a MessageDigest instance for credentials, if desired

		if (userDatabase == null)
		{
			if (throwable != null)
			{
				log.error(sm.getString("userDatabaseRealm.noDatabase"), throwable);
				throw new LifecycleException(sm.getString("userDatabaseRealm.noDatabase"), throwable);
			}
			else
			{
				throw new LifecycleException(sm.getString("userDatabaseRealm.noDatabase"));
			}
		}
	}
	/**
	 * Gracefully terminate the active use of the public methods of this
	 * component.  This method should be the last one called on a given
	 * instance of this component.  It should also send a LifecycleEvent
	 * of type STOP_EVENT to any registered listeners.
	 *
	 * @exception LifecycleException if this component detects a fatal error
	 *  that needs to be reported
	 */
	public void stop() throws LifecycleException
	{
		// Validate and update our current component state
		if (!started)
		{
			log.info(sm.getString("userdatabaseRealm.notStarted"));
			return;
		}
		lifecycle.fireLifecycleEvent(STOP_EVENT, null);
		started = false;
	}

	/**
	 * Log a message on the Logger associated with our Container (if any)
	 *
	 * @param message Message to be logged
	 */
	protected void log(String message)
	{

		Logger logger = null;
		String name = null;
		if (container != null)
		{
			logger = container.getLogger();
			name = container.getName();
		}

		if (logger != null)
		{
			logger.log(getName() + "[" + name + "]: " + message);
		}
		else
		{
			System.out.println(getName() + "[" + name + "]: " + message);
		}

	}

	/**
	 * Log a message on the Logger associated with our Container (if any)
	 *
	 * @param message Message to be logged
	 * @param throwable Associated exception
	 */
	protected void log(String message, Throwable throwable)
	{

		Logger logger = null;
		String name = null;
		if (container != null)
		{
			logger = container.getLogger();
			name = container.getName();
		}

		if (logger != null)
		{
			logger.log(getName() + "[" + name + "]: " + message, throwable);
		}
		else
		{
			System.out.println(getName() + "[" + name + "]: " + message);
			throwable.printStackTrace(System.out);
		}
	}
}
