package org.apache.commons.jcs3.utils.discovery;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;

import org.apache.commons.jcs3.engine.CacheInfo;
import org.apache.commons.jcs3.log.Log;
import org.apache.commons.jcs3.log.LogManager;
import org.apache.commons.jcs3.utils.discovery.UDPDiscoveryMessage.BroadcastType;
import org.apache.commons.jcs3.utils.serialization.StandardSerializer;

/**
 * This is a generic sender for the UDPDiscovery process.
 * <p>
 * @author Aaron Smuts
 */
public class UDPDiscoverySender implements AutoCloseable
{
    /** The logger. */
    private static final Log log = LogManager.getLog( UDPDiscoverySender.class );

    /** The socket */
    private final MulticastSocket localSocket;

    /** The address */
    private final InetAddress multicastAddress;

    /** The port */
    private final int multicastPort;

    /** Used to serialize messages */
    private final StandardSerializer serializer = new StandardSerializer();

    /**
     * Constructor for the UDPDiscoverySender object
     * <p>
     * This sender can be used to send multiple messages.
     * <p>
     * When you are done sending, you should destroy the socket sender.
     * <p>
     * @param host
     * @param port
     * @param udpTTL the Datagram packet time-to-live
     * @throws IOException
     */
    public UDPDiscoverySender( final String host, final int port, final int udpTTL )
        throws IOException
    {
        try
        {
            log.debug( "Constructing socket for sender on port [{0}]", port );
            localSocket = new MulticastSocket( port );
            if (udpTTL > 0)
            {
                log.debug( "Setting datagram TTL to [{0}]", udpTTL );
                localSocket.setTimeToLive(udpTTL);
            }

            // Remote address.
            multicastAddress = InetAddress.getByName( host );
        }
        catch ( final IOException e )
        {
            log.error( "Could not bind to multicast address [{0}]", host, e );
            throw e;
        }

        this.multicastPort = port;
    }

    /**
     * Closes the socket connection.
     */
    @Override
    public void close()
    {
        if ( this.localSocket != null && !this.localSocket.isClosed() )
        {
            this.localSocket.close();
        }
    }

    /**
     * Send messages.
     * <p>
     * @param message
     * @throws IOException
     */
    public void send( final UDPDiscoveryMessage message )
        throws IOException
    {
        if ( this.localSocket == null )
        {
            throw new IOException( "Socket is null, cannot send message." );
        }

        if ( this.localSocket.isClosed() )
        {
            throw new IOException( "Socket is closed, cannot send message." );
        }

        log.debug( "sending UDPDiscoveryMessage, address [{0}], port [{1}], "
                + "message = {2}", multicastAddress, multicastPort, message );

        final byte[] bytes = serializer.serialize( message );

        // put the byte array in a packet
        final DatagramPacket packet = new DatagramPacket( bytes, bytes.length, multicastAddress, multicastPort );

        log.debug( "Sending DatagramPacket with {0} bytes to {1}:{2}",
                bytes.length, multicastAddress, multicastPort );

        localSocket.send( packet );
    }

    /**
     * Ask other to broadcast their info the the multicast address. If a lateral is non receiving it
     * can use this. This is also called on startup so we can get info.
     * <p>
     * @throws IOException
     */
    public void requestBroadcast()
        throws IOException
    {
        log.debug( "sending requestBroadcast" );

        final UDPDiscoveryMessage message = new UDPDiscoveryMessage();
        message.setRequesterId( CacheInfo.listenerId );
        message.setMessageType( BroadcastType.REQUEST );
        send( message );
    }

    /**
     * This sends a message broadcasting out that the host and port is available for connections.
     * <p>
     * It uses the vmid as the requesterDI
     * @param host
     * @param port
     * @param cacheNames
     * @throws IOException
     */
    public void passiveBroadcast( final String host, final int port, final ArrayList<String> cacheNames )
        throws IOException
    {
        passiveBroadcast( host, port, cacheNames, CacheInfo.listenerId );
    }

    /**
     * This allows you to set the sender id. This is mainly for testing.
     * <p>
     * @param host
     * @param port
     * @param cacheNames names of the cache regions
     * @param listenerId
     * @throws IOException
     */
    protected void passiveBroadcast( final String host, final int port, final ArrayList<String> cacheNames, final long listenerId )
        throws IOException
    {
        log.debug( "sending passiveBroadcast" );

        final UDPDiscoveryMessage message = new UDPDiscoveryMessage();
        message.setHost( host );
        message.setPort( port );
        message.setCacheNames( cacheNames );
        message.setRequesterId( listenerId );
        message.setMessageType( BroadcastType.PASSIVE );
        send( message );
    }

    /**
     * This sends a message broadcasting our that the host and port is no longer available.
     * <p>
     * It uses the vmid as the requesterID
     * <p>
     * @param host host
     * @param port port
     * @param cacheNames names of the cache regions
     * @throws IOException on error
     */
    public void removeBroadcast( final String host, final int port, final ArrayList<String> cacheNames )
        throws IOException
    {
        removeBroadcast( host, port, cacheNames, CacheInfo.listenerId );
    }

    /**
     * This allows you to set the sender id. This is mainly for testing.
     * <p>
     * @param host host
     * @param port port
     * @param cacheNames names of the cache regions
     * @param listenerId listener ID
     * @throws IOException on error
     */
    protected void removeBroadcast( final String host, final int port, final ArrayList<String> cacheNames, final long listenerId )
        throws IOException
    {
        log.debug( "sending removeBroadcast" );

        final UDPDiscoveryMessage message = new UDPDiscoveryMessage();
        message.setHost( host );
        message.setPort( port );
        message.setCacheNames( cacheNames );
        message.setRequesterId( listenerId );
        message.setMessageType( BroadcastType.REMOVE );
        send( message );
    }
}

/**
 * This allows us to get the byte array from an output stream.
 * <p>
 * @author asmuts
 * @created January 15, 2002
 * @deprecated No longer used
 */
@Deprecated
class MyByteArrayOutputStream
    extends ByteArrayOutputStream
{
    /**
     * Gets the bytes attribute of the MyByteArrayOutputStream object
     * @return The bytes value
     */
    public byte[] getBytes()
    {
        return buf;
    }
}
