/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2009 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.smartclient.internal;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

import javax.management.ObjectName;

import org.ow2.easybeans.component.itf.RegistryComponent;
import org.ow2.easybeans.component.smartclient.server.SmartClientEndPointComponent;
import org.ow2.jonas.jmx.JmxService;
import org.ow2.jonas.lib.service.AbsServiceImpl;
import org.ow2.jonas.service.ServiceException;
import org.ow2.jonas.smartclient.SmartclientService;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;
import org.ow2.util.url.URLUtils;

/**
 * Implements the smartclient service.
 * @see org.ow2.jonas.smartclient.SmartclientService
 *
 * @author S. Ali Tokmen
 */
public class SmartclientServiceImpl extends AbsServiceImpl implements SmartclientService, SmartclientServiceImplMBean {

    /**
     * Logger.
     */
    private static Log logger = LogFactory.getLog(SmartclientService.class);

    /**
     * Reference to an MBean server.
     */
    private JmxService jmxService = null;

    /**
     * Port number to listen on.
     */
    private int port = 0;

    /**
     * Smartclient endpoint component.
     */
    private SmartClientEndPointComponent smartclient = null;

    /**
     * @param jmxService JMX service to set.
     */
    public void setJmxService(final JmxService jmxService) {
        this.jmxService = jmxService;
    }

    /**
     * @param port Port number to set.
     */
    public void setPort(final int port) {
        this.port = port;
    }

    /**
     * @param domainName Server's domain name.
     * @return JMX name of the smartclient service management bean.
     */
    public static ObjectName getObjectName(final String domainName) {
        try {
            return ObjectName.getInstance(domainName + ":type=service,name=smartclient");
        } catch (Exception e) {
            throw new IllegalStateException("Cannot get smartclient service", e);
        }
    }

    /**
     * Starts the EasyBeans smartclient service and registers the management
     * bean with JMX.
     *
     * @throws ServiceException If starting the EasyBeans Smartclient fails.
     */
    @Override
    protected void doStart() throws ServiceException {
        try {
            this.smartclient = new SmartClientEndPointComponent();
            this.smartclient.setPortNumber(this.port);

            RegistryComponent registry = new SmartclientServiceRegistryComponent();
            this.smartclient.setRegistryComponent(registry);

            File clientJar = new File(System.getProperty("jonas.root"), "lib/client.jar");
            URL[] clientJarURL = new URL[] { URLUtils.fileToURL(clientJar) };
            URLClassLoader clientJarClassLoader = new URLClassLoader(clientJarURL);
            this.smartclient.setClassLoader(clientJarClassLoader);

            this.smartclient.init();
            this.smartclient.start();
        } catch (Exception e) {
            throw new ServiceException("Cannot start the EasyBeans Smartclient", e);
        }

        this.jmxService.registerMBean(this, getObjectName(getDomainName()));
        logger.info("Smartclient listening on port " + getPort());
    }

    /**
     * Stops the EasyBeans smartclient service and unregisters the management
     * bean from JMX.
     *
     * @throws ServiceException If stopping the EasyBeans Smartclient fails.
     */
    @Override
    protected void doStop() throws ServiceException {
        try {
            this.smartclient.stop();
            this.smartclient = null;
        } catch (Exception e) {
            throw new ServiceException("Cannot stop the EasyBeans Smartclient", e);
        }

        this.jmxService.unregisterMBean(getObjectName(getDomainName()));
        logger.info("Smartclient service stopped and management bean unregistered");
    }

    /**
     * {@inheritDoc}, returns -1 if the EasyBeans Smartclient has not been
     * started yet.
     */
    public int getPort() {
        if (this.smartclient == null) {
            return -1;
        } else {
            return this.smartclient.getPortNumber();
        }
    }

    /**
     * {@inheritDoc}
     */
    public boolean isActive() {
        return (this.smartclient != null);
    }

}
