package cz.muni.fi.rtc.teacherWorkbench.importer;

import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.TeamPlatform;
import com.ibm.team.repository.common.TeamRepositoryException;
import com.novell.ldap.LDAPConnection;
import com.novell.ldap.LDAPException;

import cz.muni.fi.rtc.teacherWorkbench.importer.exceptions.ConfigurationException;
import cz.muni.fi.rtc.teacherWorkbench.importer.exceptions.ImporterException;

/**
 * Utility static methods used for methods used by different classes
 * 
 * @author Jan Stastny
 * 
 */
public class Utils {

	private static Log log = LogFactory
			.getLog(cz.muni.fi.rtc.teacherWorkbench.importer.Utils.class);

	private static LDAPConnection ldapConnection = null;

	private static ITeamRepository repo = null;

	/**
	 * Returns LDAP connection. Connection is established if there is no
	 * connection yet
	 * 
	 * @return LDAP connection
	 */
	public static LDAPConnection establishLdapConnection(
			ImporterConfiguration configuration) throws ImporterException {

		if (ldapConnection == null) {
			if (configuration.getLdapServer() == null
					|| configuration.getLdapServer().equals("")) {
				throw new ConfigurationException("ldapServer not configured");
			}
			if (configuration.getLdapBaseDN() == null) {
				throw new ConfigurationException("ldapBaseDN not configured");
			}
			if (configuration.getLdapAdminDN() == null) {
				throw new ConfigurationException("ldapAdminDN not configured");
			}
			if (configuration.getLdapAdminPassword() == null) {
				throw new ConfigurationException(
						"ldapAdminPassword not configured");
			}

			try {
				ldapConnection = new LDAPConnection();
				ldapConnection.connect(configuration.getLdapServer(),
						configuration.getLdapPort());
				ldapConnection.bind(LDAPConnection.LDAP_V3, configuration
						.getLdapAdminDN(), configuration.getLdapAdminPassword()
						.getBytes());

			} catch (LDAPException e) {
				throw new ImporterException(e);
			}

		}
		return ldapConnection;

	}

	/**
	 * Connects to RTC repository (if not already connected)
	 * 
	 * @return RTC repository connection
	 * @throws ImporterException
	 *             Wraps connection exceptions
	 */
	public static ITeamRepository establishRepositoryConnection(
			final ImporterConfiguration configuration) throws ImporterException {
		if (repo == null) {

			if (configuration.getRtcAddress() == null
					|| configuration.getRtcAddress().equals("")) {
				throw new ConfigurationException("rtcServer not configured");
			}
			if (configuration.getRtcAdminUser() == null
					|| configuration.getRtcAdminUser().equals("")) {
				throw new ConfigurationException("RtcAdminUser not configured");
			}
			if (configuration.getRtcAdminPassword() == null) {
				throw new ConfigurationException(
						"RtcAdminPassword not configured");
			}

			TeamPlatform.startup();
			repo = TeamPlatform.getTeamRepositoryService().getTeamRepository(
					configuration.getRtcAddress());
			repo.registerLoginHandler(new ITeamRepository.ILoginHandler() {
				public ILoginInfo challenge(ITeamRepository repository) {
					return new ILoginInfo() {
						public String getUserId() {
							return configuration.getRtcAdminUser();
						}

						public String getPassword() {
							return configuration.getRtcAdminPassword();
						}
					};
				}
			});
			log.debug("Contacting " + repo.getRepositoryURI() + "...");
			// monitor.subTask("Contacting " + repository.getRepositoryURI() +
			// "...");
			try {
				repo.login(null);
			} catch (TeamRepositoryException e) {
				throw new ImporterException(
						"Error establishing repository connection", e);
			}
			// monitor.subTask("Connected");
			log.debug("Connected to RTC server");
		}
		return repo;

	}
	

	/**
	 * Reads configuration from .properties file and returns them as the ImporterConfiguration.
	 * Default values are available for some properties. 
	 * 
* Example configuration file: * *
	 * #### LDAP ####
	 * ldapServer = localhost
	 * ldapPort = 10389
	 * ldapAdminDN = uid=admin\,ou=system
	 * ldapAdminPassword = secret
	 * ldapBaseDN = o=localhost
	 * ldapGroupJazzUsers = cn=JazzUsers\,ou=JazzGroups\,o=localhost
	 * ldapGroupPeople = ou=people\,o=localhost
	 * 
	 * #### SMTP ####
	 * smtpHost = localhost
	 * emailFromAddress = root@localhost
	 * # optional -- dafault "RTC Administrator"
	 * emailFromName = RTC Administrator
	 * # optional -- default 25
	 * smtpPort = 25 
	 * # optional -- default false
	 * smtpTls = false 
	 * # optional -- default empty
	 * smtpUser = 
	 * # optional -- default empty
	 * smtpPassword = 
	 * 
	 * ## Example SMTP for GMAIL			
	 * #smtpHost = smtp.gmail.com
	 * #smtpTls = true # optional -- default false
	 * #smtpPort = 587
	 * #smtpUser = honza.stastny@gmail.com
	 * #smtpPassword = password
	 * #emailFromAddress = honza.stastny@gmail.com
	 * 
	 * 
	 * 
	 * #### RTC Repository ####
	 * rtcAddress = https://localhost:9443/jazz
	 * rtcAdminUser = jstastny
	 * rtcAdminPassword = jstastny
	 * 
* * @param confPath Path to the configuration file * @return Importer configuration based on the properties file * @throws org.apache.commons.configuration.ConfigurationException If the configuration is invalid */ public static ImporterConfiguration configurationFromProperties(String confPath) throws org.apache.commons.configuration.ConfigurationException { CompositeConfiguration config = new CompositeConfiguration(); config.addConfiguration(new PropertiesConfiguration(confPath)); ImporterConfigurationImpl conf = new ImporterConfigurationImpl(); // LDAP conf.setLdapServer(config.getString("ldapServer")); conf.setLdapPort(config.getInt("ldapPort")); conf.setLdapBaseDN(config.getString("ldapBaseDN")); conf.setLdapAdminDN(config.getString("ldapAdminDN")); conf.setLdapAdminPassword(config.getString("ldapAdminPassword")); conf.setLdapGroupJazzUsers(config.getString("ldapGroupJazzUsers")); conf.setLdapGroupPeople(config.getString("ldapGroupPeople")); // SMTP conf.setSmtpHost(config.getString("smtpHost")); conf.setSmtpPort(config.getInt("smtpPort", 25)); conf.setEmailFromAddress(config.getString("emailFromAddress")); conf.setEmailFromName(config.getString("emailFromName", "RTC Administrator")); conf.setSmtpTls(config.getBoolean("smtpTls", false)); conf.setSmtpUser(config.getString("smtpUser", "")); conf.setSmtpPassword(config.getString("smtpPassword", "")); // RTC Repository conf.setRtcAddress(config.getString("rtcAddress")); conf.setRtcAdminUser(config.getString("rtcAdminUser")); conf.setRtcAdminPassword(config.getString("rtcAdminPassword")); return conf; } }