/*
 *  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.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * This class is used to represent a network interface of the local device. An
 * interface is defined by its address and a platform dependent name. The class
 * provides methods to get all information about the available interfaces of the
 * system or to identify the local interface of a joined multicast group.
 */
public final class NetworkInterface extends Object {

    private static final int CHECK_CONNECT_NO_PORT = -1;

    static final int NO_INTERFACE_INDEX = 0;
    static final int UNSET_INTERFACE_INDEX = -1;

    private final String name;
    private final String displayName;
    private final List<InterfaceAddress> interfaceAddresses = new LinkedList<InterfaceAddress>();

    private final List<InetAddress> addresses = new LinkedList<InetAddress>();

    // The interface index is a positive integer which is non-negative. Where
    // value is zero then we do not have an index for the interface (which
    // occurs in systems which only support IPV4)
    private int interfaceIndex;

    private NetworkInterface parent = null;

    private final List<NetworkInterface> children = new LinkedList<NetworkInterface>();

    // BEGIN android-changed: we pay this extra complexity on the Java side
    // in return for vastly simpler native code.
    private static native InterfaceAddress[] getAllInterfaceAddressesImpl() throws SocketException;

    private static NetworkInterface[] getNetworkInterfacesImpl() throws SocketException {
        Map<String, NetworkInterface> networkInterfaces = new LinkedHashMap<String, NetworkInterface>();
        for (InterfaceAddress ia : getAllInterfaceAddressesImpl()) {
            if (ia != null) { // The array may contain harmless null elements.
                String name = ia.name;
                NetworkInterface ni = networkInterfaces.get(name);
                if (ni == null) {
                    ni = new NetworkInterface(name, name, new InetAddress[] { ia.address }, ia.index);
                    ni.interfaceAddresses.add(ia);
                    networkInterfaces.put(name, ni);
                } else {
                    ni.addresses.add(ia.address);
                    ni.interfaceAddresses.add(ia);
                }
            }
        }
        return networkInterfaces.values().toArray(new NetworkInterface[networkInterfaces.size()]);
    }
    // END android-changed

    /**
     * This constructor is used by the native method in order to construct the
     * NetworkInterface objects in the array that it returns.
     *
     * @param name
     *            internal name associated with the interface.
     * @param displayName
     *            a user interpretable name for the interface.
     * @param addresses
     *            the Internet addresses associated with the interface.
     * @param interfaceIndex
     *            an index for the interface. Only set for platforms that
     *            support IPV6.
     */
    NetworkInterface(String name, String displayName, InetAddress[] addresses,
            int interfaceIndex) {
        this.name = name;
        this.displayName = displayName;
        this.interfaceIndex = interfaceIndex;
        if (addresses != null) {
            for (InetAddress address : addresses) {
                this.addresses.add(address);
            }
        }
    }

    /**
     * Returns the index for the network interface. Unless the system supports
     * IPV6 this will be 0.
     *
     * @return the index
     */
    int getIndex() {
        return interfaceIndex;
    }

    /**
     * Returns the first address for the network interface. This is used in the
     * natives when we need one of the addresses for the interface and any one
     * will do
     *
     * @return the first address if one exists, otherwise null.
     */
    InetAddress getFirstAddress() {
        if (addresses.size() >= 1) {
            return addresses.get(0);
        }
        return null;
    }

    /**
     * Gets the name associated with this network interface.
     *
     * @return the name of this {@code NetworkInterface} instance.
     */
    public String getName() {
        return name;
    }

    /**
     * Gets a list of addresses bound to this network interface.
     *
     * @return the address list of the represented network interface.
     */
    public Enumeration<InetAddress> getInetAddresses() {
        SecurityManager sm = System.getSecurityManager();
        if (sm == null || addresses.isEmpty()) {
            return Collections.enumeration(addresses);
        }
        // TODO: Android should ditch SecurityManager and the associated pollution.
        List<InetAddress> result = new ArrayList<InetAddress>(addresses.size());
        for (InetAddress address : addresses) {
            try {
                sm.checkConnect(address.getHostName(), CHECK_CONNECT_NO_PORT);
            } catch (SecurityException e) {
                continue;
            }
            result.add(address);
        }
        return Collections.enumeration(result);
    }

    /**
     * Gets the human-readable name associated with this network interface.
     *
     * @return the display name of this network interface or the name if the
     *         display name is not available.
     */
    public String getDisplayName() {
        /*
         * we should return the display name unless it is blank in this case
         * return the name so that something is displayed.
         */
        return displayName.isEmpty() ? name : displayName;
    }

    /**
     * Gets the specific network interface according to a given name.
     *
     * @param interfaceName
     *            the name to identify the searched network interface.
     * @return the network interface with the specified name if one exists or
     *         {@code null} otherwise.
     * @throws SocketException
     *             if an error occurs while getting the network interface
     *             information.
     * @throws NullPointerException
     *             if the given interface's name is {@code null}.
     */
    public static NetworkInterface getByName(String interfaceName) throws SocketException {
        if (interfaceName == null) {
            throw new NullPointerException();
        }
        for (NetworkInterface networkInterface : getNetworkInterfacesList()) {
            if (networkInterface.name.equals(interfaceName)) {
                return networkInterface;
            }
        }
        return null;
    }

    /**
     * Gets the specific network interface according to the given address.
     *
     * @param address
     *            the address to identify the searched network interface.
     * @return the network interface with the specified address if one exists or
     *         {@code null} otherwise.
     * @throws SocketException
     *             if an error occurs while getting the network interface
     *             information.
     * @throws NullPointerException
     *             if the given interface address is invalid.
     */
    public static NetworkInterface getByInetAddress(InetAddress address) throws SocketException {
        if (address == null) {
            throw new NullPointerException("address == null");
        }
        for (NetworkInterface networkInterface : getNetworkInterfacesList()) {
            if (networkInterface.addresses.contains(address)) {
                return networkInterface;
            }
        }
        return null;
    }

    /**
     * Gets a list of all network interfaces available on the local system or
     * {@code null} if no interface is available.
     *
     * @return the list of {@code NetworkInterface} instances representing the
     *         available interfaces.
     * @throws SocketException
     *             if an error occurs while getting the network interface
     *             information.
     */
    public static Enumeration<NetworkInterface> getNetworkInterfaces() throws SocketException {
        return Collections.enumeration(getNetworkInterfacesList());
    }

    private static List<NetworkInterface> getNetworkInterfacesList() throws SocketException {
        NetworkInterface[] interfaces = getNetworkInterfacesImpl();

        for (NetworkInterface netif : interfaces) {
            // Ensure that current NetworkInterface is bound to at least
            // one InetAddress before processing
            for (InetAddress addr : netif.addresses) {
                if (addr.ipaddress.length == 16) {
                    if (addr.isLinkLocalAddress() || addr.isSiteLocalAddress()) {
                        ((Inet6Address) addr).scopedIf = netif;
                        ((Inet6Address) addr).ifname = netif.name;
                        ((Inet6Address) addr).scope_ifname_set = true;
                    }
                }
            }
        }

        List<NetworkInterface> result = new ArrayList<NetworkInterface>();
        boolean[] peeked = new boolean[interfaces.length];
        for (int counter = 0; counter < interfaces.length; counter++) {
            // If this interface has been touched, continue.
            if (peeked[counter]) {
                continue;
            }
            int counter2 = counter;
            // Checks whether the following interfaces are children.
            for (; counter2 < interfaces.length; counter2++) {
                if (peeked[counter2]) {
                    continue;
                }
                if (interfaces[counter2].name.startsWith(interfaces[counter].name + ":")) {
                    // Tagged as peeked
                    peeked[counter2] = true;
                    interfaces[counter].children.add(interfaces[counter2]);
                    interfaces[counter2].parent = interfaces[counter];
                    interfaces[counter].addresses.addAll(interfaces[counter2].addresses);
                }
            }
            // Tagged as peeked
            result.add(interfaces[counter]);
            peeked[counter] = true;
        }
        return result;
    }

    /**
     * Compares the specified object to this {@code NetworkInterface} and
     * returns whether they are equal or not. The object must be an instance of
     * {@code NetworkInterface} with the same name, {@code displayName} and list
     * of network interfaces to be equal.
     *
     * @param obj
     *            the object to compare with this instance.
     * @return {@code true} if the specified object is equal to this {@code
     *         NetworkInterface}, {@code false} otherwise.
     * @see #hashCode()
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof NetworkInterface)) {
            return false;
        }
        NetworkInterface rhs = (NetworkInterface) obj;
        // TODO: should the order of the addresses matter (we use List.equals)?
        return interfaceIndex == rhs.interfaceIndex &&
                name.equals(rhs.name) && displayName.equals(rhs.displayName) &&
                addresses.equals(rhs.addresses);
    }

    /**
     * Returns the hash code for this {@code NetworkInterface}. Since the
     * name should be unique for each network interface the hash code is
     * generated using this name.
     */
    @Override
    public int hashCode() {
        return name.hashCode();
    }

    /**
     * Gets a string containing a concise, human-readable description of this
     * network interface.
     *
     * @return the textual representation for this network interface.
     */
    @Override
    public String toString() {
        StringBuilder string = new StringBuilder(25);
        string.append("[");
        string.append(name);
        string.append("][");
        string.append(displayName);
        // BEGIN android-added: the RI shows this, and it's useful for IPv6 users.
        string.append("][");
        string.append(interfaceIndex);
        // END android-added
        string.append("]");

        /*
         * get the addresses through this call to make sure we only reveal those
         * that we should
         */
        Enumeration<InetAddress> theAddresses = getInetAddresses();
        if (theAddresses != null) {
            while (theAddresses.hasMoreElements()) {
                InetAddress nextAddress = theAddresses.nextElement();
                string.append("[");
                string.append(nextAddress.toString());
                string.append("]");
            }
        }
        return string.toString();
    }

    /**
     * Returns a List the InterfaceAddresses for this network interface.
     * <p>
     * If there is a security manager, its checkConnect method is called with
     * the InetAddress for each InterfaceAddress. Only InterfaceAddresses where
     * the checkConnect doesn't throw a SecurityException will be returned.
     *
     * @return a List of the InterfaceAddresses for this network interface.
     * @since 1.6
     */
    public List<InterfaceAddress> getInterfaceAddresses() {
        SecurityManager sm = System.getSecurityManager();
        if (sm == null) {
            return Collections.unmodifiableList(interfaceAddresses);
        }
        // TODO: Android should ditch SecurityManager and the associated pollution.
        List<InterfaceAddress> result = new ArrayList<InterfaceAddress>(interfaceAddresses.size());
        for (InterfaceAddress ia : interfaceAddresses) {
            try {
                sm.checkConnect(ia.getAddress().getHostName(), CHECK_CONNECT_NO_PORT);
            } catch (SecurityException e) {
                continue;
            }
            result.add(ia);
        }
        return result;
    }

    /**
     * Returns an {@code Enumeration} of all the sub-interfaces of this network interface.
     * Sub-interfaces are also known as virtual interfaces.
     * <p>
     * For example, {@code eth0:1} would be a sub-interface of {@code eth0}.
     *
     * @return an Enumeration of all the sub-interfaces of this network interface
     * @since 1.6
     */
    public Enumeration<NetworkInterface> getSubInterfaces() {
        return Collections.enumeration(children);
    }

    /**
     * Returns the parent NetworkInterface of this interface if this is a
     * sub-interface, or null if it's a physical (non virtual) interface.
     *
     * @return the NetworkInterface this interface is attached to.
     * @since 1.6
     */
    public NetworkInterface getParent() {
        return parent;
    }

    /**
     * Returns true if this network interface is up.
     *
     * @return true if the interface is up.
     * @throws SocketException if an I/O error occurs.
     * @since 1.6
     */
    public boolean isUp() throws SocketException {
        if (addresses.isEmpty()) {
            return false;
        }
        return isUpImpl(name);
    }
    private static native boolean isUpImpl(String n) throws SocketException;

    /**
     * Returns true if this network interface is a loopback interface.
     *
     * @return true if the interface is a loopback interface.
     * @throws SocketException if an I/O error occurs.
     * @since 1.6
     */
    public boolean isLoopback() throws SocketException {
        if (addresses.isEmpty()) {
            return false;
        }
        return isLoopbackImpl(name);
    }
    private static native boolean isLoopbackImpl(String n) throws SocketException;

    /**
     * Returns true if this network interface is a point-to-point interface.
     * (For example, a PPP connection using a modem.)
     *
     * @return true if the interface is point-to-point.
     * @throws SocketException if an I/O error occurs.
     * @since 1.6
     */
    public boolean isPointToPoint() throws SocketException {
        if (addresses.isEmpty()) {
            return false;
        }
        return isPointToPointImpl(name);
    }
    private static native boolean isPointToPointImpl(String n) throws SocketException;

    /**
     * Returns true if this network interface supports multicast.
     *
     * @throws SocketException if an I/O error occurs.
     * @since 1.6
     */
    public boolean supportsMulticast() throws SocketException {
        if (addresses.isEmpty()) {
            return false;
        }
        return supportsMulticastImpl(name);
    }
    private static native boolean supportsMulticastImpl(String n) throws SocketException;

    /**
     * Returns the hardware address of the interface, if it has one, and the
     * user has the necessary privileges to access the address.
     *
     * @return a byte array containing the address or null if the address
     *         doesn't exist or is not accessible.
     * @throws SocketException if an I/O error occurs.
     * @since 1.6
     */
    public byte[] getHardwareAddress() throws SocketException {
        if (addresses.isEmpty()) {
            return new byte[0];
        }
        return getHardwareAddressImpl(name);
    }
    private static native byte[] getHardwareAddressImpl(String n) throws SocketException;

    /**
     * Returns the Maximum Transmission Unit (MTU) of this interface.
     *
     * @return the value of the MTU for the interface.
     * @throws SocketException if an I/O error occurs.
     * @since 1.6
     */
    public int getMTU() throws SocketException {
        if (addresses.isEmpty()) {
            return 0;
        }
        return getMTUImpl(name);
    }
    private static native int getMTUImpl(String n) throws SocketException;

    /**
     * Returns true if this interface is a virtual interface (also called
     * a sub-interface). Virtual interfaces are, on some systems, interfaces
     * created as a child of a physical interface and given different settings
     * (like address or MTU). Usually the name of the interface will the name of
     * the parent followed by a colon (:) and a number identifying the child,
     * since there can be several virtual interfaces attached to a single
     * physical interface.
     *
     * @return true if this interface is a virtual interface.
     * @since 1.6
     */
    public boolean isVirtual() {
        return parent != null;
    }
}
