/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2007 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$
 * --------------------------------------------------------------------------
 */
/**
 * Handles DiscGreeting in Master instances of JGroups discovery.
 * @author eyindanga
 */
package org.ow2.jonas.discovery.jgroups.comm.handler;

import java.io.IOException;

import org.jgroups.Address;
import org.jgroups.Message;
import org.objectweb.util.monolog.api.BasicLevel;
import org.ow2.jonas.discovery.DiscoveryState;
import org.ow2.jonas.discovery.base.comm.DiscGreeting;
import org.ow2.jonas.discovery.jgroups.utils.Data;
import org.ow2.jonas.discovery.jgroups.utils.JGroupsDiscoveryUtils;
import org.ow2.jonas.lib.util.Log;

/**
 * @author eyindanga
 * Handles discovery greetings for given Host.
 * if greeting state is <code>STARTING_UP</code>
 * that means another server has sent a greeting message with its identification (<code>domainName, serveName, serveId</code>)
 * if greeting state is <code>DUPLICATE_NAME</code>
 * that means another server has already started in the domain, with the same configuration.
 */
public class DiscCommGreetingHandler extends DiscCommHandlerImpl {


    /**Constructor.
     * @param hostAddress discovery address.
     */
    public DiscCommGreetingHandler(final Address hostAddress) {
        super(hostAddress);
        // TODO Auto-generated constructor stub
    }

    /* (non-Javadoc)
     * @see org.ow2.jonas.discovery.jgroups.comm.DiscCommReceiverImpl#receive(org.jgroups.Message)
     */
    @Override
    public void receive(final Message msg) {
        if (logger == null) {
            logger = Log.getLogger(Log.JONAS_DISCOVERY_PREFIX);
        }
        Object objReceived = null;
        Data data = null;
        logger.log(BasicLevel.DEBUG, " Hi all on " +multicastAddress+ ". My name is "+ hostName+". I've received greeting message from "+msg.getSrc());
        Address senderAddress = msg.getSrc();

        //Ignore messages received from this host.
        data = (Data) msg.getObject();
        try {
            objReceived = JGroupsDiscoveryUtils.bytesToObject(data);
        }catch (IOException e) {
            logger.log(BasicLevel.DEBUG, " IOException occured in DiscCommGreetingHandler. Unable to cast data received on network into Object. Received packet content must not be the expected one \n"+e);
        }catch (Exception e) {
            logger.log(BasicLevel.DEBUG, " Following Exception occurred in DiscCommGreetingHandler. Unable to cast data received on network into Object. Received packet content must not be the expected one \n"+e);
        }
        if (objReceived != null) {
            if (objReceived instanceof DiscGreeting) {
                //received a discovery Greeting Message
                DiscGreeting message = (DiscGreeting) objReceived;
                try {
                    handleGreeting(message, senderAddress);
                } catch (Exception e) {
                    logger.log(BasicLevel.DEBUG, " Exception occurend while handling Greeting: "+e);
                }

            }
        }
    }

    /**
     * Executed when Discovery greeting is received.
     * @param message the message to handle.
     * @param add2Reply the host to reply.
     * @throws Exception any
     */
    private void handleGreeting(final DiscGreeting message, final Address add2Reply) throws Exception{
        logger.log(BasicLevel.DEBUG, " My name is"+ hostName +". Handling greeting message received from "+ message.getSourceAddress());
        /**
         * Server is identified by its Id.
         */
        if (message.getState().equals(DiscoveryState.STARTUP)) {
            if (message.getDomainName().equals(JGroupsDiscoveryUtils.getInstance().getServerId())&& message.getServerName().equals(JGroupsDiscoveryUtils.getInstance().getServerId())) {
                logger.log(BasicLevel.DEBUG, " My name is " + hostName + ". I will send DuplicateServerNameException to " + message.getSourceAddress() + " \n");
                DiscGreeting duplicateNameNotif = JGroupsDiscoveryUtils.createDiscGreeting(false);
                JGroupsDiscoveryUtils.send(add2Reply, JGroupsDiscoveryUtils.objectToBytes(duplicateNameNotif));
            }
        }else if(message.getState().equals(DiscoveryState.DUPLICATE_NAME)) {
            JGroupsDiscoveryUtils.duplicateExceptionName = true;
            logger.log(BasicLevel.INFO, " My name is "+ hostName +". Cannot go on starting. A server named "+message.getServerName()+" hosted on "+message.getSourceAddress()+" As already started with my configuration on domain: "+message.getDomainName()+"\n");
            logger.log(BasicLevel.INFO, " You may change my 'name' or my 'domain name' to resolve this problem.\n");
            //die
            Thread.interrupted();
        }

    }
}
