package org.jvnet.glassfish.comms.deployment.backend;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.sip.SipApplicationRouter;

import org.jvnet.glassfish.comms.util.LogUtil;

import com.ericsson.ssa.container.sim.ApplicationDispatcher;
import com.sun.enterprise.deployment.interfaces.pluggable.ArchiveDescriptor;
import com.sun.enterprise.deployment.interfaces.pluggable.ArchiveLoader;



/**
 * <p>This class is the loader class for SIP Application Routers
 *   
 * An instance of this class is registered with the ExtensionModuleDeployer for 
 * the module Type that represents Application Routers. The ExtensionModuleLoader 
 * retrieves an instance of this class from the ExtensionModuleDeployer and calls
 * the load/unload methods. </p>
 *  
 * @author yvo.bogers@ericsson.com
 */
public class ArArchiveLoader implements ArchiveLoader {

	private static LogUtil theirLog = new LogUtil(LogUtil.SIP_LOG_DOMAIN);
	private static final String LOGPREFIX = 
		"org.jvnet.glassfish.comms.deployment.backend.ArArchiveLoader.";
	
	/**
	 * will instantiate the application router which aDescriptor refers to, and
	 * pass a reference to the ApplicationDispatcher.
	 */
	public boolean load(ArchiveDescriptor aDescriptor, boolean isEnableAction) 
		throws Exception {

		if (theirLog.isLoggable(Level.FINEST)) {
			theirLog.log(Level.FINEST, LOGPREFIX + "loading");
		}			

		try{
			String clazz =
				((ArArchiveDescriptor)aDescriptor).getApplicationRouterClass();
			
			if (theirLog.isLoggable(Level.FINEST)) {
				theirLog.log(
					Level.FINEST, LOGPREFIX + "loading_router_class", clazz);
			}

			ClassLoader loader = aDescriptor.getModuleClassLoader();
			
			Class<SipApplicationRouter> routerClass =
				(Class<SipApplicationRouter>) (loader.loadClass(clazz));
			SipApplicationRouter router = routerClass.newInstance();
			
			if (theirLog.isLoggable(Level.FINEST)) {
				theirLog.log(Level.FINEST, LOGPREFIX + "loaded_router", router);
			}
			
			ApplicationDispatcher ad = ApplicationDispatcher.getInstance();
			if (theirLog.isLoggable(Level.FINEST)) {
				theirLog.log(Level.FINEST, LOGPREFIX + "ad_reference", ad);
				theirLog.log(Level.FINEST, LOGPREFIX + "ad_classloader: ", 
					ad.getClass().getClassLoader());
			}
			ad.setApplicationRouter(router);

//	    	The following would cause a ClassNotFoundException in the AD:
//	    	ad.setApplicationRouterClass(clazz);
	    	
		}
		catch (Exception e){
			theirLog.severe(LOGPREFIX + "failed_loading_ar", e.getMessage());
			e.printStackTrace();
		}
	
		return true;
	}

	public boolean unload(ArchiveDescriptor aDescriptor, boolean isDisableAction) 
		throws Exception {
		
		if (theirLog.isLoggable(Level.FINEST)) {
			theirLog.log(Level.FINEST, LOGPREFIX + "unloading");
		}
		
		// TODO lookup the application Dispatcher and unload the current 
		// application router?
		
		
		return true;
	}
}
