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

// BEGIN android-note
// Address length was changed from long to int for performance reasons.
// Harmony implements INetworkSystem's methods with native methods; Android
// implements them with Java that call through to native wrappers.
// TODO: change the native code to eliminate the wrappers
// END android-note

package org.apache.harmony.luni.platform;

import java.io.FileDescriptor;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketImpl;
import java.net.UnknownHostException;
import java.nio.channels.Channel;
// BEGIN android-removed
// import java.nio.channels.SelectableChannel;
// END android-removed

/**
 * This wraps native code that implements the INetworkSystem interface.
 */
final class OSNetworkSystem implements INetworkSystem {

    private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
    private static final int ERRORCODE_SOCKET_INTERRUPTED = -208;

    private static final int INETADDR_REACHABLE = 0;

    // private static boolean isNetworkInited = false; android-removed

    private static OSNetworkSystem singleton = new OSNetworkSystem();

    /**
     * Answers the unique instance of the OSNetworkSystem.
     *
     * @return the network system interface instance
     */
    public static OSNetworkSystem getOSNetworkSystem() {
        return singleton;
    }

    // Can not be instantiated.
    private OSNetworkSystem() {
        super();
    }

    public void accept(FileDescriptor fdServer, SocketImpl newSocket,
            FileDescriptor fdnewSocket, int timeout) throws IOException {
        acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
    }

    static native void acceptSocketImpl(FileDescriptor fdServer,
            SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
            throws IOException;

    /**
     * Associates a local address with a socket.
     *
     * @param fd
     *            the socket descriptor
     * @param port
     *            the port number
     * @param inetAddress
     *            address to bind
     * @throws SocketException
     *             thrown if bind operation fails
     */
    public void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException {
        socketBindImpl(fd, port, inetAddress);
    }

    static native void socketBindImpl(FileDescriptor aFD, int port, InetAddress inetAddress) throws SocketException;

    // BEGIN android-changed (removed unused return value and useless native method)
    public void connect(FileDescriptor fd, int trafficClass,
            InetAddress inetAddress, int port) throws IOException{
        connectStreamWithTimeoutSocketImpl(fd, port, 0, trafficClass, inetAddress);
    }
    // END android-changed

    public void connectDatagram(FileDescriptor fd, int port,
            int trafficClass, InetAddress inetAddress) throws SocketException {
        connectDatagramImpl2(fd, port, trafficClass, inetAddress);
    }

    static native void connectDatagramImpl2(FileDescriptor aFD, int port,
            int trafficClass, InetAddress inetAddress) throws SocketException;

    public void connectStreamWithTimeoutSocket(FileDescriptor aFD,
            int aport, int timeout, int trafficClass, InetAddress inetAddress)
            throws IOException {
        connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
                inetAddress);
    }

    static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
            int aport, int timeout, int trafficClass, InetAddress inetAddress)
            throws IOException;

    // BEGIN android-changed
    // changed context from Long to byte[]
    public int connectWithTimeout(FileDescriptor fd, int timeout,
            int trafficClass, InetAddress inetAddress, int port, int step,
            byte[] context) throws IOException {
        return connectWithTimeoutSocketImpl(fd, timeout, trafficClass,
                inetAddress, port, step, context);
    }

    static native int connectWithTimeoutSocketImpl(FileDescriptor aFD,
            int timeout, int trafficClass, InetAddress hostname, int port, int step,
            byte[] context);
    // END android-changed

    public void createDatagramSocket(FileDescriptor fd,
            boolean preferIPv4Stack) throws SocketException {
        createDatagramSocketImpl(fd, preferIPv4Stack);
    }

    /*
    * Allocate a datagram socket in the IP stack. The socket is associated with
    * the <code>aFD</code>.
    *
    * @param aFD the FileDescriptor to associate with the socket @param
    * preferIPv4Stack IP stack preference if underlying platform is V4/V6
    * @exception SocketException upon an allocation error
    */
    static native void createDatagramSocketImpl(FileDescriptor aFD,
            boolean preferIPv4Stack) throws SocketException;

    public void createServerStreamSocket(FileDescriptor fd,
            boolean preferIPv4Stack) throws SocketException {
        createServerStreamSocketImpl(fd, preferIPv4Stack);
    }

    /*
     * Answer the result of attempting to create a server stream socket in the
     * IP stack. Any special options required for server sockets will be set by
     * this method.
     *
     * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
     * @exception SocketException if an error occurs while creating the socket
     */
    static native void createServerStreamSocketImpl(FileDescriptor aFD,
            boolean preferIPv4Stack) throws SocketException;

    public void createStreamSocket(FileDescriptor fd,
            boolean preferIPv4Stack) throws SocketException {
        createStreamSocketImpl(fd, preferIPv4Stack);
    }

    static native void createStreamSocketImpl(FileDescriptor aFD,
            boolean preferIPv4Stack) throws SocketException;

    /**
     * Disconnect the socket to a port and address
     *a
     * @param fd
     *            the FileDescriptor associated with the socket
     *
     * @throws SocketException
     *             if the disconnect fails
     */
    public void disconnectDatagram(FileDescriptor fd)
            throws SocketException {
        disconnectDatagramImpl(fd);
    }

    static native void disconnectDatagramImpl(FileDescriptor aFD)
            throws SocketException;

    public InetAddress getHostByAddr(byte[] ipAddress)
            throws UnknownHostException {
        // BEGIN android-changed
        // Wallpaper fix for http://b/1851257. This  is a layering violation,
        // but at least the method has the right return type.
        // TODO: Fix the socket code to remove this method altogether.
        return InetAddress.getByAddress(ipAddress);
        // END android-changed
    }
    // BEGIN android-removed
    // static native InetAddress getHostByAddrImpl(byte[] addr)
    //         throws UnknownHostException;
    // END android-removed

    // BEGIN android-changed: remove useless IPv6 check.
    public InetAddress getHostByName(String hostName) throws UnknownHostException {
        return InetAddress.getByName(hostName);
    }
    // END android-changed

    // BEGIN android-removed
    // static native InetAddress getHostByNameImpl(String addr) throws UnknownHostException;
    // END android-removed

    public native String byteArrayToIpString(byte[] address)
            throws UnknownHostException;

    public native byte[] ipStringToByteArray(String address)
            throws UnknownHostException;

    public InetAddress getSocketLocalAddress(FileDescriptor fd) {
        return getSocketLocalAddressImpl(fd);
    }
    static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD);

    public int getSocketLocalPort(FileDescriptor aFD) {
        return getSocketLocalPortImpl(aFD);
    }
    static native int getSocketLocalPortImpl(FileDescriptor aFD);

    /**
     * Query the IP stack for the nominated socket option.
     *
     * @param fd
     *            the socket descriptor
     * @param opt
     *            the socket option type
     * @return the nominated socket option value
     * @throws SocketException
     *             if the option is invalid
     */
    public Object getSocketOption(FileDescriptor fd, int opt)
            throws SocketException {
        return getSocketOptionImpl(fd, opt);
    }

    static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
            throws SocketException;

    public native Channel inheritedChannel();

    // BEGIN android-removed
    // public boolean isReachableByICMP(final InetAddress dest,
    //         InetAddress source, final int ttl, final int timeout) {
    //     return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
    //     timeout);
    // }

    // native int isReachableByICMPImpl(InetAddress addr,
    //         InetAddress local, int ttl, int timeout);
    // END android-removed

    public void listenStreamSocket(FileDescriptor aFD, int backlog)
            throws SocketException {
        listenStreamSocketImpl(aFD, backlog);
    }

    static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
            throws SocketException;

    // BEGIN android-removed: we do this statically, when we start the VM.
    // public void oneTimeInitialization(boolean jcl_supports_ipv6);
    // native void oneTimeInitializationImpl(boolean jcl_supports_ipv6);
    // END android-removed

    /**
     * Peek on the socket, update <code>sender</code> address and answer the
     * sender port.
     *
     * @param fd
     *            the socket FileDescriptor
     * @param sender
     *            an InetAddress, to be updated with the sender's address
     * @param receiveTimeout
     *            the maximum length of time the socket should block, reading
     * @return the sender port
     *
     * @throws IOException
     *             upon an read error or timeout
     */
    public int peekDatagram(FileDescriptor fd, InetAddress sender,
            int receiveTimeout) throws IOException {
        return peekDatagramImpl(fd, sender, receiveTimeout);
    }

    static native int peekDatagramImpl(FileDescriptor aFD,
            InetAddress sender, int receiveTimeout) throws IOException;

    /**
     * Read available bytes from the given file descriptor into a byte array.
     *
     * The read has an optional timeout parameter, which if non-zero is the
     * length of time that the read will wait on a select call to see if any
     * bytes are available for reading. If the timeout expires the method
     * returns zero to indicate no bytes were read.
     *
     * @param fd
     *            the socket file descriptor to read
     * @param data
     *            the byte array in which to store the results
     * @param offset
     *            the offset into the byte array in which to start reading the
     *            results
     * @param count
     *            the maximum number of bytes to read
     * @param timeout
     *            the length of time to wait for the bytes, in milliseconds; or
     *            zero to indicate no timeout applied. When there is no timeout
     *            applied the read may block based upon socket options.
     * @return number of bytes read, or zero if there were no bytes available
     *         before the timeout occurred, or -1 to indicate the socket is
     *         closed
     * @throws IOException
     *             if an underlying socket exception occurred
     */
    public int read(FileDescriptor fd, byte[] data, int offset, int count,
            int timeout) throws IOException {
        // BEGIN android-added safety!
        if (offset < 0 || count < 0 || offset > data.length - count) {
            throw new IllegalArgumentException("data.length=" + data.length + " offset=" + offset +
                    " count=" + count);
        }
        // END android-added
        return readSocketImpl(fd, data, offset, count, timeout);
    }

    static native int readSocketImpl(FileDescriptor aFD, byte[] data,
            int offset, int count, int timeout) throws IOException;

    /**
     * Read available bytes from the given file descriptor into OS memory at a
     * given address.
     *
     * @param fd
     *            the socket file descriptor to read
     * @param address
     *            the address of the memory in which to store the results
     * @param count
     *            the maximum number of bytes to read
     * @param timeout
     *            the length of time to wait for the bytes, in milliseconds
     * @return number of bytes read, or zero if there were no bytes available
     *         before the timeout occurred, or -1 to indicate the socket is
     *         closed
     * @throws IOException
     *             if an underlying socket exception occurred
     */
    public int readDirect(FileDescriptor fd, int address, int count,
            int timeout) throws IOException {
        return readSocketDirectImpl(fd, address, count, timeout);
    }

    static native int readSocketDirectImpl(FileDescriptor aFD, int address, int count,
            int timeout) throws IOException;

    /**
     * Receive data on the socket into the specified buffer. The packet fields
     * <code>data</code> & <code>length</code> are passed in addition to
     * <code>packet</code> to eliminate the JNI field access calls.
     *
     * @param fd
     *            the socket FileDescriptor
     * @param packet
     *            the DatagramPacket to receive into
     * @param data
     *            the data buffer of the packet
     * @param offset
     *            the offset in the data buffer
     * @param length
     *            the length of the data buffer in the packet
     * @param receiveTimeout
     *            the maximum length of time the socket should block, reading
     * @param peek
     *            indicates to peek at the data
     * @return number of data received
     * @throws IOException
     *             upon an read error or timeout
     */
    public int receiveDatagram(FileDescriptor fd, DatagramPacket packet,
            byte[] data, int offset, int length, int receiveTimeout,
            boolean peek) throws IOException {
        return receiveDatagramImpl(fd, packet, data, offset, length,
                receiveTimeout, peek);
    }

    static native int receiveDatagramImpl(FileDescriptor aFD,
            DatagramPacket packet, byte[] data, int offset, int length,
            int receiveTimeout, boolean peek) throws IOException;

    public int receiveDatagramDirect(FileDescriptor fd,
            DatagramPacket packet, int address, int offset, int length,
            int receiveTimeout, boolean peek) throws IOException {
        return receiveDatagramDirectImpl(fd, packet, address, offset, length,
                receiveTimeout, peek);
    }

    static native int receiveDatagramDirectImpl(FileDescriptor aFD,
            DatagramPacket packet, int address, int offset, int length,
            int receiveTimeout, boolean peek) throws IOException;

    /**
     * Receive data on the connected socket into the specified buffer. The
     * packet fields <code>data</code> and <code>length</code> are passed in
     * addition to <code>packet</code> to eliminate the JNI field access calls.
     *
     * @param fd
     *            the socket FileDescriptor
     * @param packet
     *            the DatagramPacket to receive into
     * @param data
     *            the data buffer of the packet
     * @param offset
     *            the offset in the data buffer
     * @param length
     *            the length of the data buffer in the packet
     * @param receiveTimeout
     *            the maximum length of time the socket should block, reading
     * @param peek
     *            indicates to peek at the data
     * @return number of data received
     * @throws IOException
     *             upon an read error or timeout
     */
    public int recvConnectedDatagram(FileDescriptor fd,
            DatagramPacket packet, byte[] data, int offset, int length,
            int receiveTimeout, boolean peek) throws IOException {
        return recvConnectedDatagramImpl(fd, packet, data, offset, length,
                receiveTimeout, peek);
    }

    static native int recvConnectedDatagramImpl(FileDescriptor aFD,
            DatagramPacket packet, byte[] data, int offset, int length,
            int receiveTimeout, boolean peek) throws IOException;

    public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
            int offset, int length, int receiveTimeout, boolean peek)
            throws IOException {
        return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
    }

    static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
            DatagramPacket packet, int address, int offset, int length,
            int receiveTimeout, boolean peek) throws IOException;


    public boolean select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
            int numReadable, int numWritable, long timeout, int[] flags)
            throws SocketException {
        if (numReadable < 0 || numWritable < 0) {
            throw new IllegalArgumentException();
        }

        int total = numReadable + numWritable;
        if (total == 0) {
            return true;
        }

        assert validateFDs(readFDs, writeFDs, numReadable, numWritable) : "Invalid file descriptor arrays"; //$NON-NLS-1$

        // BEGIN android-changed: handle errors in native code
        return selectImpl(readFDs, writeFDs, numReadable, numWritable, flags, timeout);
        // END android-changed
    }

    // BEGIN android-changed: return type (we throw in native code, with descriptive errors)
    static native boolean selectImpl(FileDescriptor[] readfd,
            FileDescriptor[] writefd, int cread, int cwirte, int[] flags,
            long timeout);
    // END android-changed

    /**
     * Send the <code>data</code> to the address and port to which the was
     * connected and <code>port</code>.
     *
     * @param fd
     *            the socket FileDescriptor
     * @param data
     *            the data buffer of the packet
     * @param offset
     *            the offset in the data buffer
     * @param length
     *            the length of the data buffer in the packet
     * @param bindToDevice
     *            not used, current kept in case needed as was the case for
     *            sendDatagramImpl
     * @return number of data send
     * @throws IOException
     *             upon an read error or timeout
     */
    public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
            int offset, int length, boolean bindToDevice) throws IOException {
        return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
    }

    static native int sendConnectedDatagramImpl(FileDescriptor fd,
            byte[] data, int offset, int length, boolean bindToDevice)
            throws IOException;

    public int sendConnectedDatagramDirect(FileDescriptor fd,
            int address, int offset, int length, boolean bindToDevice)
            throws IOException {
        return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
    }
    static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
            int address, int offset, int length, boolean bindToDevice)
            throws IOException;

    /**
     * Send the <code>data</code> to the nominated target <code>address</code>
     * and <code>port</code>. These values are derived from the DatagramPacket
     * to reduce the field calls within JNI.
     *
     * @param fd
     *            the socket FileDescriptor
     * @param data
     *            the data buffer of the packet
     * @param offset
     *            the offset in the data buffer
     * @param length
     *            the length of the data buffer in the packet
     * @param port
     *            the target host port
     * @param bindToDevice
     *            if bind to device
     * @param trafficClass
     *            the traffic class to be used when the datagram is sent
     * @param inetAddress
     *            address to connect to.
     * @return number of data send
     *
     * @throws IOException
     *             upon an read error or timeout
     */
    public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
            int length, int port, boolean bindToDevice, int trafficClass,
            InetAddress inetAddress) throws IOException {
        return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
                trafficClass, inetAddress);
    }

    static native int sendDatagramImpl(FileDescriptor fd, byte[] data, int offset,
            int length, int port, boolean bindToDevice, int trafficClass,
            InetAddress inetAddress) throws IOException;

    public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
            int length, int port, InetAddress inetAddress) throws IOException {
        return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
    }

    static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
            int offset, int length, int port, InetAddress inetAddress) throws IOException;


    public int sendDatagramDirect(FileDescriptor fd, int address,
            int offset, int length, int port, boolean bindToDevice,
            int trafficClass, InetAddress inetAddress) throws IOException {
        return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
                trafficClass, inetAddress);
    }

    static native int sendDatagramDirectImpl(FileDescriptor fd, int address,
            int offset, int length, int port, boolean bindToDevice,
            int trafficClass, InetAddress inetAddress) throws IOException;

    public void sendUrgentData(FileDescriptor fd, byte value) {
        sendUrgentDataImpl(fd, value);
    }

    static native void sendUrgentDataImpl(FileDescriptor fd, byte value);

    public void setInetAddress(InetAddress sender, byte[] address) {
        setInetAddressImpl(sender, address);
    }

    native void setInetAddressImpl(InetAddress sender, byte[] address);

    public void setNonBlocking(FileDescriptor fd, boolean block)
            throws IOException {
        setNonBlockingImpl(fd, block);
    }

    static native void setNonBlockingImpl(FileDescriptor aFD, boolean block);

    /**
     * Set the nominated socket option in the IP stack.
     *
     * @param aFD
     *            the socket descriptor @param opt the option selector @param
     *            optVal the nominated option value
     *
     * @throws SocketException
     *             if the option is invalid or cannot be set
     */
    public void setSocketOption(FileDescriptor aFD, int opt,
            Object optVal) throws SocketException {
        setSocketOptionImpl(aFD, opt, optVal);
    }

    static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
            Object optVal) throws SocketException;

    public void shutdownInput(FileDescriptor descriptor) throws IOException {
        shutdownInputImpl(descriptor);
    }

    private native void shutdownInputImpl(FileDescriptor descriptor)
            throws IOException;

    public void shutdownOutput(FileDescriptor fd) throws IOException {
        shutdownOutputImpl(fd);
    }

    private native void shutdownOutputImpl(FileDescriptor descriptor)
            throws IOException;
    /**
     * Close the socket in the IP stack.
     *
     * @param fd
     *            the socket descriptor
     */
    public void socketClose(FileDescriptor fd) throws IOException {
        socketCloseImpl(fd);
    }

    static native void socketCloseImpl(FileDescriptor fD);

    public boolean supportsUrgentData(FileDescriptor fd) {
        return supportsUrgentDataImpl(fd);
    }

    static native boolean supportsUrgentDataImpl(FileDescriptor fd);

    /*
    * Used to check if the file descriptor arrays are valid before passing them
    * into the select native call.
    */
    private boolean validateFDs(FileDescriptor[] readFDs,
            FileDescriptor[] writeFDs) {
        for (FileDescriptor fd : readFDs) {
            // Also checks fd not null
            if (!fd.valid()) {
                return false;
            }
        }
        for (FileDescriptor fd : writeFDs) {
            if (!fd.valid()) {
                return false;
            }
        }
        return true;
    }

    private boolean validateFDs(FileDescriptor[] readFDs,
            FileDescriptor[] writeFDs, int countRead, int countWrite) {
        for (int i = 0; i < countRead; ++i) {
            // Also checks fd not null
            if (!readFDs[i].valid()) {
                return false;
            }
        }
        for (int i = 0; i < countWrite; ++i) {
            if (!writeFDs[i].valid()) {
                return false;
            }
        }
        return true;
    }

    /**
     * Write bytes from a byte array to a socket.
     *
     * @param fd
     *            the socket on which to write the bytes
     * @param data
     *            the array containing the bytes to be written
     * @param offset
     *            the offset in the byte array from which to take the bytes
     * @param count
     *            the maximum number of bytes to be written. Callers are trusted
     *            not to send values of length+count that are larger than
     *            data.length
     * @return the actual number of bytes written, which will be between zero
     *         and count
     * @throws IOException
     *             if there is an underlying socket problem
     */
    public int write(FileDescriptor fd, byte[] data, int offset, int count)
            throws IOException {
        return writeSocketImpl(fd, data, offset, count);
    }

    static native int writeSocketImpl(FileDescriptor fd, byte[] data, int offset,
            int count) throws IOException;


    /**
     * Write bytes from the given address to a socket.
     *
     * @param fd
     *            the socket on which to write the bytes
     * @param address
     *            the start address of the bytes to be written
     * @param count
     *            the maximum number of bytes to be written
     * @return the actual number of bytes written, which will be between zero
     *         and count
     * @throws IOException
     *             if there is an underlying socket problem
     */
    public int writeDirect(FileDescriptor fd, int address, int offset, int count)
            throws IOException {
        return writeSocketDirectImpl(fd, address, offset, count);
    }

    static native int writeSocketDirectImpl(FileDescriptor fd, int address, int offset, int count)
            throws IOException;

    // BEGIN android-removed
    // /**
    //  * Write given buffers to a socket. The given buffers is a Object array, the
    //  * element of array must be direct buffer or a byte array to be written.
    //  *
    //  * @param fd
    //  *            the socket on which to write the bytes
    //  * @param buffers
    //  *            the element of array must be direct buffer or a byte array to
    //  *            be written
    //  * @param offsets
    //  *            the index of the first byte to be write
    //  * @param counts
    //  *            the maximum number of bytes to be written
    //  * @param length
    //  *            the size of buffer array
    //  * @return the actual number of bytes written
    //  * @throws IOException
    //  *             if there is an underlying socket problem
    //  */
    // public native int writev(FileDescriptor fd, Object[] buffers,
    //         int[] offsets, int[] counts, int length) throws IOException;
    // END android-removed
}
