package lu.tudor.santec.gecamed.core.test;

import java.io.File;
import java.net.Socket;
import java.util.Properties;
import java.util.logging.Handler;

import javax.naming.InitialContext;
import javax.security.auth.login.LoginContext;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.slf4j.bridge.SLF4JBridgeHandler;

import lu.tudor.santec.gecamed.core.gui.JaasJbossConfiguration;
import lu.tudor.santec.gecamed.core.gui.LoginCallbackHandler;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.beans.LoginBean;
import lu.tudor.santec.gecamed.usermanagement.ejb.session.interfaces.LoginInterface;

/**
 * @author jens.ferring(at)tudor.lu
 * 
 * @version
 * <br>$Log: TestUtils.java,v $
 */

public class TestUtils
{
	/* ======================================== */
	// CONSTANTS
	/* ======================================== */
	
	private static final String LOGFILE	= System.getProperty("user.home") + File.separator + "GecamedTestLog";
	
	
	
	/* ======================================== */
	// MEMBERS
	/* ======================================== */
	
	/** the logger Object for this class */
	private static Logger logger;
	
	private static boolean jbossConnectionInitialized = false;
	
	
	
	/* ======================================== */
	// CLASS BODY
	/* ======================================== */
	
	public static void initLogger ()
	{
		if (logger != null)
			return;
		
		/* ---------------------------------------- */
		// INIT THE org.apache.log4j.Logger
		/* ---------------------------------------- */
		
		try
		{
			// create an initial logger
			File	logfile	= new File(LOGFILE);
			logfile.getParentFile().mkdirs();
			
			Logger.getRootLogger().removeAllAppenders();
			
			// define the logging layouts
			Layout fileLayout = new PatternLayout("%d{yyyy-MM-dd HH:mm:ss,SSS} %c %M (line %L)%n%p: %m%n");
			Layout consoleLayout = fileLayout;
			
			// set the logger
			ConsoleAppender consoleAppender = new ConsoleAppender(consoleLayout);
			Logger.getRootLogger().addAppender(consoleAppender);
			
			RollingFileAppender fileAppender = new RollingFileAppender(
					fileLayout,
					logfile.getAbsolutePath(),
					true);
			fileAppender.setMaxFileSize("5MB");
			fileAppender.setMaxBackupIndex(3);
			fileAppender.setEncoding("UTF-8");
			fileAppender.setName("GECAMed default Logger");
			BasicConfigurator.configure(fileAppender);
			
			// define level for logging levels
			Logger.getRootLogger().setLevel(Level.INFO);
			
			logger = Logger.getLogger(TestUtils.class.getName());
			logger.log(Level.INFO, "org.apache.log4j works!");
		}
		catch (Exception e)
		{
			e.printStackTrace();
			logger = Logger.getLogger(TestUtils.class.getName());
			logger.log(Level.ERROR, "Error initializing log4j Logger", e);
		}
		
		
		/* ---------------------------------------- */
		// INIT THE java.util.Logger
		/* ---------------------------------------- */
		
		try 
		{
			SLF4JBridgeHandler.uninstall();
			for (Handler h : java.util.logging.Logger.getLogger("").getHandlers())
				java.util.logging.Logger.getLogger("").removeHandler(h);
			SLF4JBridgeHandler.install();
			
			java.util.logging.Logger.getLogger(TestUtils.class.getName()).info("java.util.logging works!");
		}
		catch (Exception e) 
		{
			e.printStackTrace();
			logger.log(Level.WARN, "setting up java.util.logging.Logger failed" ,e);
		}
	}
	
	
	public static void initJBossConnection ()
	{
		LoginContext			lc;
		LoginCallbackHandler	callbackHandler;
		LoginInterface			login;
		
		
		if (jbossConnectionInitialized)
			return;
		
		initLogger();
		
		try
		{
//			BasicService bs = (BasicService) ServiceManager.lookup("javax.jnlp.BasicService");
			Properties connectionProperties = new Properties();
			connectionProperties.load(TestUtils.class.getResourceAsStream("resources/connection.properties"));
			
			String	username	= connectionProperties.getProperty("jboss.login");
			String	password	= connectionProperties.getProperty("jboss.password");
			String	host		= connectionProperties.getProperty("jboss.host");
			String	port		= connectionProperties.getProperty("jboss.port");
			
			System.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
			System.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
			System.setProperty("java.naming.provider.url", host + ":" + port);
			
			try
			{
				// test the connection to the JBoss
				new Socket(host, Integer.parseInt(port));
			}
			catch (Exception e)
			{
				throw new RuntimeException("JBoss not reachable at " + host + ":" + port, e);
			}
			
			login = (LoginInterface) ManagerFactory.getRemote(LoginBean.class);
			
			// no error yet, the connection to the JBoss is established
			// -> login
			
			// manage JAAS login to JBoss
			JaasJbossConfiguration.activateConfiguration();
			callbackHandler = new LoginCallbackHandler(
					username,
					password);	
			
			lc = new LoginContext("gecam_login", callbackHandler); 
			lc.login();
				
			// get a reference to the LoginBean
			new InitialContext();
			
			// load the user that just logged in.
			// this will fail and throw a security exception on an invalid login
			login.getCurrentUser();
			
			jbossConnectionInitialized = true;
		}
		catch (Exception e)
		{
			throw new RuntimeException("Error connecting to the JBoss", e);
		}
	}
}
