/*
 *  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.
 */

package java.net;

import java.io.IOException;
import java.util.Enumeration;
import libcore.io.IoUtils;

/**
 * This class implements a multicast socket for sending and receiving IP
 * multicast datagram packets.
 *
 * @see DatagramSocket
 */
public class MulticastSocket extends DatagramSocket {
    /**
     * Stores the address supplied to setInterface so we can return it from getInterface. The
     * translation to an interface index is lossy because an interface can have multiple addresses.
     */
    private InetAddress setAddress;

    /**
     * Constructs a multicast socket, bound to any available port on the
     * local host.
     *
     * @throws IOException if an error occurs.
     */
    public MulticastSocket() throws IOException {
        setReuseAddress(true);
    }

    /**
     * Constructs a multicast socket, bound to the specified {@code port} on the
     * local host.
     *
     * @throws IOException if an error occurs.
     */
    public MulticastSocket(int port) throws IOException {
        super(port);
        setReuseAddress(true);
    }

    /**
     * Constructs a {@code MulticastSocket} bound to the address and port specified by
     * {@code localAddress}, or an unbound {@code MulticastSocket} if {@code localAddress == null}.
     *
     * @throws IllegalArgumentException if {@code localAddress} is not supported (because it's not
     * an {@code InetSocketAddress}, say).
     * @throws IOException if an error occurs.
     */
    public MulticastSocket(SocketAddress localAddress) throws IOException {
        super(localAddress);
        setReuseAddress(true);
    }

    /**
     * Returns an address of the outgoing network interface used by this socket. To avoid
     * inherent unpredictability, new code should use {@link #getNetworkInterface} instead.
     *
     * @throws SocketException if an error occurs.
     */
    public InetAddress getInterface() throws SocketException {
        checkOpen();
        if (setAddress != null) {
            return setAddress;
        }
        InetAddress ipvXaddress = (InetAddress) impl.getOption(SocketOptions.IP_MULTICAST_IF);
        if (ipvXaddress.isAnyLocalAddress()) {
            // the address was not set at the IPv4 level so check the IPv6
            // level
            NetworkInterface theInterface = getNetworkInterface();
            if (theInterface != null) {
                Enumeration<InetAddress> addresses = theInterface.getInetAddresses();
                if (addresses != null) {
                    while (addresses.hasMoreElements()) {
                        InetAddress nextAddress = addresses.nextElement();
                        if (nextAddress instanceof Inet6Address) {
                            return nextAddress;
                        }
                    }
                }
            }
        }
        return ipvXaddress;
    }

    /**
     * Returns the outgoing network interface used by this socket.
     *
     * @throws SocketException if an error occurs.
     */
    public NetworkInterface getNetworkInterface() throws SocketException {
        checkOpen();
        int index = (Integer) impl.getOption(SocketOptions.IP_MULTICAST_IF2);
        if (index != 0) {
            return NetworkInterface.getByIndex(index);
        }
        return NetworkInterface.forUnboundMulticastSocket();
    }

    /**
     * Returns the time-to-live (TTL) for multicast packets sent on this socket.
     *
     * @throws IOException if an error occurs.
     */
    public int getTimeToLive() throws IOException {
        checkOpen();
        return impl.getTimeToLive();
    }

    /**
     * Returns the time-to-live (TTL) for multicast packets sent on this socket.
     *
     * @throws IOException if an error occurs.
     * @deprecated Use {@link #getTimeToLive} instead.
     */
    @Deprecated
    public byte getTTL() throws IOException {
        checkOpen();
        return impl.getTTL();
    }

    /**
     * Adds this socket to the specified multicast group. A socket must join a
     * group before data may be received. A socket may be a member of multiple
     * groups but may join any group only once.
     *
     * @param groupAddr
     *            the multicast group to be joined.
     * @throws IOException if an error occurs.
     */
    public void joinGroup(InetAddress groupAddr) throws IOException {
        checkJoinOrLeave(groupAddr);
        impl.join(groupAddr);
    }

    /**
     * Adds this socket to the specified multicast group. A socket must join a
     * group before data may be received. A socket may be a member of multiple
     * groups but may join any group only once.
     *
     * @param groupAddress
     *            the multicast group to be joined.
     * @param netInterface
     *            the network interface on which the datagram packets will be
     *            received.
     * @throws IOException
     *                if the specified address is not a multicast address.
     * @throws IllegalArgumentException
     *                if no multicast group is specified.
     */
    public void joinGroup(SocketAddress groupAddress, NetworkInterface netInterface) throws IOException {
        checkJoinOrLeave(groupAddress, netInterface);
        impl.joinGroup(groupAddress, netInterface);
    }

    /**
     * Removes this socket from the specified multicast group.
     *
     * @param groupAddr
     *            the multicast group to be left.
     * @throws NullPointerException
     *                if {@code groupAddr} is {@code null}.
     * @throws IOException
     *                if the specified group address is not a multicast address.
     */
    public void leaveGroup(InetAddress groupAddr) throws IOException {
        checkJoinOrLeave(groupAddr);
        impl.leave(groupAddr);
    }

    /**
     * Removes this socket from the specified multicast group.
     *
     * @param groupAddress
     *            the multicast group to be left.
     * @param netInterface
     *            the network interface on which the addresses should be
     *            dropped.
     * @throws IOException
     *                if the specified group address is not a multicast address.
     * @throws IllegalArgumentException
     *                if {@code groupAddress} is {@code null}.
     */
    public void leaveGroup(SocketAddress groupAddress, NetworkInterface netInterface) throws IOException {
        checkJoinOrLeave(groupAddress, netInterface);
        impl.leaveGroup(groupAddress, netInterface);
    }

    private void checkJoinOrLeave(SocketAddress groupAddress, NetworkInterface netInterface) throws IOException {
        checkOpen();
        if (groupAddress == null) {
            throw new IllegalArgumentException("groupAddress == null");
        }

        if (netInterface != null && !netInterface.getInetAddresses().hasMoreElements()) {
            throw new SocketException("No address associated with interface: " + netInterface);
        }

        if (!(groupAddress instanceof InetSocketAddress)) {
            throw new IllegalArgumentException("Group address not an InetSocketAddress: " +
                    groupAddress.getClass());
        }

        InetAddress groupAddr = ((InetSocketAddress) groupAddress).getAddress();
        if (groupAddr == null) {
            throw new SocketException("Group address has no address: " + groupAddress);
        }

        if (!groupAddr.isMulticastAddress()) {
            throw new IOException("Not a multicast group: " + groupAddr);
        }
    }

    private void checkJoinOrLeave(InetAddress groupAddr) throws IOException {
        checkOpen();
        if (groupAddr == null) {
            throw new IllegalArgumentException("groupAddress == null");
        }
        if (!groupAddr.isMulticastAddress()) {
            throw new IOException("Not a multicast group: " + groupAddr);
        }
    }

    /**
     * Sends the given {@code packet} on this socket, using the given {@code ttl}. This method is
     * deprecated because it modifies the TTL socket option for this socket twice on each call.
     *
     * @throws IOException if an error occurs.
     * @deprecated Use {@link #setTimeToLive} instead.
     */
    @Deprecated
    public void send(DatagramPacket packet, byte ttl) throws IOException {
        checkOpen();
        InetAddress packAddr = packet.getAddress();
        int currTTL = getTimeToLive();
        if (packAddr.isMulticastAddress() && (byte) currTTL != ttl) {
            try {
                setTimeToLive(ttl & 0xff);
                impl.send(packet);
            } finally {
                setTimeToLive(currTTL);
            }
        } else {
            impl.send(packet);
        }
    }

    /**
     * Sets the outgoing network interface used by this socket. The interface used is the first
     * interface found to have the given {@code address}. To avoid inherent unpredictability,
     * new code should use {@link #getNetworkInterface} instead.
     *
     * @throws SocketException if an error occurs.
     */
    public void setInterface(InetAddress address) throws SocketException {
        checkOpen();
        if (address == null) {
            throw new NullPointerException("address == null");
        }

        NetworkInterface networkInterface = NetworkInterface.getByInetAddress(address);
        if (networkInterface == null) {
            throw new SocketException("Address not associated with an interface: " + address);
        }
        impl.setOption(SocketOptions.IP_MULTICAST_IF2, networkInterface.getIndex());
        this.setAddress = address;
    }

    /**
     * Sets the outgoing network interface used by this socket to the given
     * {@code networkInterface}.
     *
     * @throws SocketException if an error occurs.
     */
    public void setNetworkInterface(NetworkInterface networkInterface) throws SocketException {
        checkOpen();
        if (networkInterface == null) {
            throw new SocketException("networkInterface == null");
        }

        impl.setOption(SocketOptions.IP_MULTICAST_IF2, networkInterface.getIndex());
        this.setAddress = null;
    }

    /**
     * Sets the time-to-live (TTL) for multicast packets sent on this socket.
     * Valid TTL values are between 0 and 255 inclusive.
     *
     * @throws IOException if an error occurs.
     */
    public void setTimeToLive(int ttl) throws IOException {
        checkOpen();
        if (ttl < 0 || ttl > 255) {
            throw new IllegalArgumentException("TimeToLive out of bounds: " + ttl);
        }
        impl.setTimeToLive(ttl);
    }

    /**
     * Sets the time-to-live (TTL) for multicast packets sent on this socket.
     * Valid TTL values are between 0 and 255 inclusive.
     *
     * @throws IOException if an error occurs.
     * @deprecated Use {@link #setTimeToLive} instead.
     */
    @Deprecated
    public void setTTL(byte ttl) throws IOException {
        checkOpen();
        impl.setTTL(ttl);
    }

    @Override
    synchronized void createSocket(int aPort, InetAddress addr) throws SocketException {
        impl = factory != null ? factory.createDatagramSocketImpl() : new PlainDatagramSocketImpl();
        impl.create();
        try {
            impl.setOption(SocketOptions.SO_REUSEADDR, Boolean.TRUE);
            impl.bind(aPort, addr);
            isBound = true;
        } catch (SocketException e) {
            close();
            throw e;
        }
    }

    /**
     * Returns true if multicast loopback is <i>disabled</i>.
     * See {@link SocketOptions#IP_MULTICAST_LOOP}, and note that the sense of this is the
     * opposite of the underlying Unix {@code IP_MULTICAST_LOOP}.
     *
     * @throws SocketException if an error occurs.
     */
    public boolean getLoopbackMode() throws SocketException {
        checkOpen();
        return !((Boolean) impl.getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();
    }

    /**
     * Disables multicast loopback if {@code disable == true}.
     * See {@link SocketOptions#IP_MULTICAST_LOOP}, and note that the sense of this is the
     * opposite of the underlying Unix {@code IP_MULTICAST_LOOP}: true means disabled, false
     * means enabled.
     *
     * @throws SocketException if an error occurs.
     */
    public void setLoopbackMode(boolean disable) throws SocketException {
        checkOpen();
        impl.setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(!disable));
    }
}
