/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2007,2008 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 (at your option) 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id: DiscoveryUtils.java 21631 2011-08-12 13:35:48Z benoitf $
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.discovery.jgroups.utils;

import java.util.Map;

import org.jgroups.Address;
import org.jgroups.Event;
import org.jgroups.conf.ProtocolStackConfigurator;
import org.jgroups.stack.IpAddress;
import org.objectweb.util.monolog.api.Logger;
import org.ow2.jonas.lib.util.Log;
import org.ow2.util.cluster.jgroups.IChannel;

public class DiscoveryUtils {
    private static final Object UDP_PROTOCOL = "UDP";
    /**
     * Current discovery type.
     */
    private  String discType = JGroupsDiscoveryUtils.DISCOVERY_IS_SLAVE;
    /**
     * JGroups stack configuration.
     */
    private  ProtocolStackConfigurator stackConfigurator = null;
    /**
     * @uml.property  name="jonasName"
     */
    private  String jonasName = JGroupsDiscoveryUtils.DEFAULT_JONAS_NAME;
    /**
     * @uml.property  name="domainName"
     */
    private  String domainName = JGroupsDiscoveryUtils.DEFAULT_DOMAIN_NAME;
    /**
     * @uml.property  name="serverId"
     */
    private  String serverId = JGroupsDiscoveryUtils.DEFAULT_SERVER_ID;
    /**
     * Current logger.
     */
    private  Logger logger = Log.getLogger(Log.JONAS_DISCOVERY_PREFIX);
    /**
     * Current greeting timeout.
     */
    private  Integer greetingAckTimeOut = new Integer(JGroupsDiscoveryUtils.DISCOVERY_GREETING_TIMEOUT_DEFAULT);

    /**
     * Current discovery channel.
     */
    private  IChannel comChannel = null;
    /**
     * Current name of stack communication protocol.
     */
    public  String commProtoName = null;
    /**
     * Current configuration for communication protocol.
     */
    private  Map<String, String> commProtoProperties = null;
    /**
     * Current jmx urls of discovery host.
     */
    private  String[] urls = null;
    /**
     * Current Ip ttl.
     */
    private  Integer ttl = new Integer(JGroupsDiscoveryUtils.DISCOVERY_GREETING_TIMEOUT_DEFAULT);
    /**
     * True if communication protol is "multicast".
     */
    private boolean isMulticastDiscovery;
    /**
     * The JGroups stack configuration file.
     */
    public String configurationFile = JGroupsDiscoveryUtils.DEFAULT_STACK_FILENAME;
    /**
     * @uml.property  name="groupName"
     */
    public String groupName = JGroupsDiscoveryUtils.DEF_GROUP_NAME;
    /**
     * @return the discType
     */
    public String getDiscType() {
        return discType;
    }
    /**
     * @param discType the discType to set
     */
    public void setDiscType(final String discType) {
        this.discType = discType;
    }
    /**
     * @return the stack configurator.
     */
    public ProtocolStackConfigurator getStackConfigurator() {
        return stackConfigurator;
    }
    /**
     * @param stackconfigurator the stackconfigurator to set
     */
    public void setStackConfigurator(final ProtocolStackConfigurator stackconfigurator) {
        this.stackConfigurator = stackconfigurator;
    }
    /**
     * @return the jonasName
     */
    public String getJonasName() {
        return jonasName;
    }
    /**
     * @param jonasName the jonasName to set
     */
    public void setJonasName(final String jonasName) {
        this.jonasName = jonasName;
    }
    /**
     * @return the domainName
     */
    public String getDomainName() {
        return domainName;
    }
    /**
     * @param domainName the domainName to set
     */
    public void setDomainName(final String domainName) {
        this.domainName = domainName;
    }
    /**
     * @return the serverId
     */
    public String getServerId() {
        return serverId;
    }
    /**
     * @param serverId the serverId to set
     */
    public void setServerId(final String serverId) {
        this.serverId = serverId;
    }
    /**
     * @return the discPort
     */
    synchronized
    public Integer getDiscPort() {
        return getLocalAddress().getPort();
    }
    /**
     * @return the logger
     */
    public Logger getLogger() {
        return logger;
    }
    /**
     * @param logger the logger to set
     */
    public void setLogger(final Logger logger) {
        this.logger = logger;
    }
    /**
     * @return the greetingAckTimeOut
     */
    public Integer getGreetingAckTimeOut() {
        return greetingAckTimeOut;
    }
    /**
     * @param greetingAckTimeOut the greetingAckTimeOut to set
     */
    public void setGreetingAckTimeOut(final Integer greetingAckTimeOut) {
        this.greetingAckTimeOut = greetingAckTimeOut;
    }
    /**
     * @return the comChannel
     */
    public IChannel getComChannel() {
        return comChannel;
    }
    /**
     * @param comChannel the comChannel to set
     */
    public void setComChannel(final IChannel comChannel) {
        this.comChannel = comChannel;
    }
    /**
     * @return the commProtoName
     */
    public String getCommProtoName() {
        return commProtoName;
    }
    /**
     * @param commProtoName the commProtoName to set
     */
    public void setCommProtoName(final String commProtoName) {
        this.commProtoName = commProtoName;
    }
    /**
     * @return the commProtoParams
     */
    public Map<String, String> getCommProtoProperties() {
        return commProtoProperties;
    }
    /**
     * @param commProtoProperties the commProtoParams to set
     */
    public void setCommProtoProperties(final Map<String, String> commProtoProperties) {
        this.commProtoProperties = commProtoProperties;
    }
    /**
     * @return the urls
     */
    public String[] getUrls() {
        return urls;
    }
    /**
     * @param urls the urls to set
     */
    public void setUrls(final String[] urls) {
        this.urls = urls;
    }
    /**
     * @return the localAddress
     */
    public synchronized IpAddress getLocalAddress() {
        Address address =  comChannel.getLocalAddress();
        if (address != null) {
            address = (Address) comChannel.downcall(new Event(Event.GET_PHYSICAL_ADDRESS, address));
        }
        return (IpAddress) address;
    }
    /**
     * @return the ttl
     */
    public Integer getTtl() {
        return ttl;
    }
    /**
     * @param ttl the ttl to set
     */
    public void setTtl(final Integer ttl) {
        this.ttl = ttl;
    }
    public boolean isMulticast() {
        // TODO Auto-generated method stub
        return isMulticastDiscovery;
    }
    /**Checks if discovery is multicast.
     * @return the isMulticastDiscovery
     */
    public boolean isMulticastDiscovery() {
        return this.commProtoName.equals(UDP_PROTOCOL);
    }
    /**
     * Gets IP address of discovery.
     * @return Discovery IP
     */
    public String getDiscIp() {
        return ((IpAddress)comChannel.getLocalAddress()).getIpAddress().toString();
    }
    /**
     * @return the conFile.
     */
    public String getConfigurationFile() {
        return configurationFile;
    }
    /**
     * @param conFile the conFile to set.
     */
    public void setConfigurationFile(final String conFile) {
        this.configurationFile = conFile;
    }
    /**
     * @return the groupName.
     */
    public String getGroupName() {
        return groupName;
    }
    /**
     * @param groupName the groupName to set.
     */
    public void setGroupName(final String groupName) {
        this.groupName = groupName;
    }

}
