
package org.eclipse.virgo.kernel.config.internal;

import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Properties;

import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.cm.ConfigurationException;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * This class reads the merged shell configuration and registers it separated in the @link(ConfigurationAdmin).
 * <p />
 * 
 * <strong>Concurrent Semantics</strong><br />
 * Thread-safe.
 */
public class ConsoleConfigurationConvertor {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final BundleContext context;

    private final ConfigurationAdmin configAdmin;

    private ServiceRegistration<ManagedService> configuratorRegistration;

    private static final String CONSOLE_PID = "osgi.console";

    private static final String TELNET_PID = "osgi.console.telnet";

    private static final String SSH_PID = "osgi.console.ssh";

    private static final String TELNET_PORT = "telnet.port";

    private static final String TELNET_HOST = "telnet.host";

    private static final String TELNET_ENABLED = "telnet.enabled";

    private static final String SSH_PORT = "ssh.port";

    private static final String SSH_HOST = "ssh.host";

    private static final String SSH_ENABLED = "ssh.enabled";

    private static final String HOST = "host";

    private static final String PORT = "port";

    private static final String ENABLED = "enabled";
    
    private static final String TELNET_SERVICE = "telnet";
    
    private static final String SSH_SERVICE = "ssh";
    
    private static final Object monitor = new Object();

    ConsoleConfigurationConvertor(BundleContext context, ConfigurationAdmin configAdmin) {
        this.context = context;
        this.configAdmin = configAdmin;
    }

    public void start() {
        Dictionary<String, String> consoleProperties = new Hashtable<String, String>();
        consoleProperties.put(Constants.SERVICE_PID, CONSOLE_PID);
        synchronized (ConsoleConfigurationConvertor.monitor) {
            this.configuratorRegistration = this.context.registerService(ManagedService.class, new ConsoleConfigurator(), consoleProperties);
        }
    }

    private void updateConfiguration(String pid, String host, String port, String enabled) {
    	boolean isPortAvailable;
    	if (pid.contains(TELNET_SERVICE)) {
    		isPortAvailable = checkPortAvailability(port, enabled, TELNET_SERVICE);
    	} else {
    		isPortAvailable = checkPortAvailability(port, enabled, SSH_SERVICE);
    	}
    	
    	if(!isPortAvailable) {
    		return;
    	}
    	
        try {
            Configuration configuration = this.configAdmin.getConfiguration(pid, null);
            Dictionary<String, String> properties = new Hashtable<String, String>();
            properties.put(HOST, host);
            properties.put(PORT, port);
            properties.put(ENABLED, enabled);
            configuration.update(properties);
        } catch (IOException e) {
            String message = String.format("Unable to update configuration with pid '%s'", pid);
            this.logger.error(message, e);
        }
    }
    
    public void stop() {
    	deleteConfiguration(TELNET_PID);
    	deleteConfiguration(SSH_PID);
    	deleteConfiguration(CONSOLE_PID);
    }

    private void deleteConfiguration(String pid) {
        try {
  			Configuration configuration = configAdmin.getConfiguration(pid, null);
			configuration.delete();
    	} catch (IOException e) {
			String message = String.format("Unable to delete configuration with pid: " + pid);
            this.logger.error(message, e);
		}
    }
    
    private boolean checkPortAvailability(String portStr, String enabled, String service) {
    	if ("false".equalsIgnoreCase(enabled)) {
    		return true;
    	}
    	int port = Integer.parseInt(portStr);
    	ServerSocket socket = null;
    	try {
    		socket = new ServerSocket(port);
    		return true;
    	} catch (BindException e) {
    		String message = "Port " + port + " already in use; " + service + " access to console will not be available";
    		this.logger.error(message, e);
    	} catch (IOException e) {
			// do nothing
		} finally {
    		if (socket != null) {
    			try {
					socket.close();
				} catch (IOException e) {
					// do nothing
				}
    		}
    	}
    	return false;
    }

    class ConsoleConfigurator implements ManagedService {

        private Dictionary properties;

        @Override
        public void updated(Dictionary props) throws ConfigurationException {
            if (props != null) {
                this.properties = props;
                this.properties.put(Constants.SERVICE_PID, CONSOLE_PID);
            } else {
                return;
            }
            synchronized (ConsoleConfigurationConvertor.monitor) {
                ConsoleConfigurationConvertor.this.configuratorRegistration.setProperties(this.properties);
            }

            String telnetHost = (String) this.properties.get(TELNET_HOST);
            String telnetPort = (String) this.properties.get(TELNET_PORT);
            String telnetEnabled = (String) this.properties.get(TELNET_ENABLED);
            updateConfiguration(TELNET_PID, telnetHost, telnetPort, telnetEnabled);

            String sshHost = (String) this.properties.get(SSH_HOST);
            String sshPort = (String) this.properties.get(SSH_PORT);
            String sshEnabled = (String) this.properties.get(SSH_ENABLED);
            updateConfiguration(SSH_PID, sshHost, sshPort, sshEnabled);
        }
    }
}