/*
 * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test
 * @bug 8036979 8072384 8044773 8225214 8233296 8234083
 * @library /test/lib
 * @requires !vm.graal.enabled
 * @run main/othervm -Xcheck:jni OptionsTest
 * @run main/othervm -Xcheck:jni -Djava.net.preferIPv4Stack=true OptionsTest
 * @run main/othervm --limit-modules=java.base OptionsTest
 */

import java.lang.reflect.Method;
import java.net.*;
import java.util.*;

import jdk.test.lib.NetworkConfiguration;
import jdk.test.lib.net.IPSupport;

public class OptionsTest {

    static class Test<T> {
        final SocketOption<T> option;
        final T value;
        Test(SocketOption<T> option, T value) {
            this.option = option;
            this.value = value;
        }
        static <T> Test<T> create(SocketOption<T> option, T value) {
            return new Test<T>(option, value);
        }

    }

    // The tests set the option using the new API, read back the set value
    // which could be different, and then use the legacy get API to check
    // these values are the same

    static Test<?>[] socketTests = new Test<?>[] {
        Test.create(StandardSocketOptions.SO_KEEPALIVE, Boolean.TRUE),
        Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
        Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
        Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
        Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
        Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(-1)),
        Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(0)),
        Test.create(StandardSocketOptions.SO_LINGER, Integer.valueOf(80)),
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    };

    static Test<?>[] serverSocketTests = new Test<?>[] {
        Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
        Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
        Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    };

    static Test<?>[] datagramSocketTests = new Test<?>[] {
        Test.create(StandardSocketOptions.SO_SNDBUF, Integer.valueOf(10 * 100)),
        Test.create(StandardSocketOptions.SO_RCVBUF, Integer.valueOf(8 * 100)),
        Test.create(StandardSocketOptions.SO_REUSEADDR, Boolean.FALSE),
        Test.create(StandardSocketOptions.SO_REUSEPORT, Boolean.FALSE),
        Test.create(StandardSocketOptions.SO_BROADCAST, Boolean.FALSE),
        Test.create(StandardSocketOptions.SO_BROADCAST, Boolean.TRUE),
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(0)),  // lower-bound
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(100)),
        Test.create(StandardSocketOptions.IP_TOS, Integer.valueOf(255))  //upper-bound
    };

    static Test<?>[] multicastSocketTests = new Test<?>[] {
        Test.create(StandardSocketOptions.SO_BROADCAST, Boolean.FALSE),
        Test.create(StandardSocketOptions.SO_BROADCAST, Boolean.TRUE),
        Test.create(StandardSocketOptions.IP_MULTICAST_IF, getNetworkInterface()),
        Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(0)),   // lower-bound
        Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(10)),
        Test.create(StandardSocketOptions.IP_MULTICAST_TTL, Integer.valueOf(255)), //upper-bound
        Test.create(StandardSocketOptions.IP_MULTICAST_LOOP, Boolean.TRUE)
    };

    static NetworkInterface getNetworkInterface() {
        try {
            NetworkConfiguration nc = NetworkConfiguration.probe();
            return nc.multicastInterfaces(true).findAny().orElse(null);
        } catch (Exception e) {
        }
        return null;
    }

    static boolean okayToTest(Socket s, SocketOption<?> option) {
        if (option == StandardSocketOptions.SO_REUSEPORT) {
            // skip SO_REUSEPORT if option is not supported
            return s.supportedOptions().contains(StandardSocketOptions.SO_REUSEPORT);
        }
        if (option == StandardSocketOptions.IP_TOS && s.isConnected()) {
            // skip IP_TOS if connected
            return false;
        }
        return true;
    }

    static <T> void testEqual(SocketOption<T> option, T value1, T value2) {
        if (!value1.equals(value2)) {
            throw new RuntimeException("Test of " + option.name() + " failed: "
                    + value1 + " != " + value2);
        }
    }

    static <T> void test(Socket s, Test<T> test) throws Exception {
        SocketOption<T> option = test.option;
        s.setOption(option, test.value);
        T value1 = s.getOption(test.option);
        T value2 = (T) legacyGetOption(Socket.class, s, test.option);
        testEqual(option, value1, value2);
    }

    static <T> void test(ServerSocket ss, Test<T> test) throws Exception {
        SocketOption<T> option = test.option;
        ss.setOption(option, test.value);
        T value1 = ss.getOption(test.option);
        T value2 = (T) legacyGetOption(ServerSocket.class, ss, test.option);
        testEqual(option, value1, value2);
    }

    static <T> void test(DatagramSocket ds, Test<T> test) throws Exception {
        SocketOption<T> option = test.option;
        ds.setOption(option, test.value);
        T value1 = ds.getOption(test.option);
        T value2 = (T) legacyGetOption(ds.getClass(), ds, test.option);
        testEqual(option, value1, value2);
    }

    // Tests default and negative values of SO_LINGER. All negative values should
    // retrieve as -1.
    static void testSoLingerValues() throws Exception {
        try (Socket s = new Socket()) {
            // retrieve without set
            int defaultValue = s.getOption(StandardSocketOptions.SO_LINGER);
            testEqual(StandardSocketOptions.SO_LINGER, -1, defaultValue);

            for (int v : List.of(-1, -2, -100, -65534, -65535, -65536, -100000)) {
                System.out.println("Testing SO_LINGER with:" + v);
                s.setOption(StandardSocketOptions.SO_LINGER, v);
                int value = s.getOption(StandardSocketOptions.SO_LINGER);
                testEqual(StandardSocketOptions.SO_LINGER, -1, value);
            }
        }
    }

    @SuppressWarnings("try")
    static void doSocketTests() throws Exception {
        // unconnected socket
        try (Socket s = new Socket()) {
            for (Test<?> test : socketTests) {
                if (okayToTest(s, test.option)) {
                    test(s, test);
                }
            }
        }

        // connected socket
        try (ServerSocket ss = new ServerSocket()) {
            var loopback = InetAddress.getLoopbackAddress();
            ss.bind(new InetSocketAddress(loopback, 0));
            try (Socket s1 = new Socket()) {
                s1.connect(ss.getLocalSocketAddress());
                try (Socket s2 = ss.accept()) {
                    for (Test<?> test : socketTests) {
                        if (okayToTest(s1, test.option)) {
                            test(s1, test);
                        }
                    }
                }
            }
        }

        testSoLingerValues();
    }

    static void doServerSocketTests() throws Exception {
        try (ServerSocket ss = new ServerSocket(0)) {
            Set<SocketOption<?>> options = ss.supportedOptions();
            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
            for (Test<?> test : serverSocketTests) {
                if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
                    test(ss, test);
                }
            }
        }
    }

    static void doDatagramSocketTests() throws Exception {
        try (DatagramSocket ds = new DatagramSocket(0)) {
            Set<SocketOption<?>> options = ds.supportedOptions();
            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);
            for (Test<?> test : datagramSocketTests) {
                if (!(test.option == StandardSocketOptions.SO_REUSEPORT && !reuseport)) {
                    test(ds, test);
                }
            }
        }
    }

    static void doMulticastSocketTests() throws Exception {
        try (MulticastSocket ms = new MulticastSocket(0)) {
            for (Test<?> test : multicastSocketTests) {
                test(ms, test);
            }
        }
    }

    static Object legacyGetOption(Class<?> type, Object s, Object option) throws Exception {
        if (type.equals(Socket.class)) {
            Socket socket = (Socket)s;
            Set<SocketOption<?>> options = socket.supportedOptions();
            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);

            if (option.equals(StandardSocketOptions.SO_KEEPALIVE)) {
                return Boolean.valueOf(socket.getKeepAlive());
            } else if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
                return Integer.valueOf(socket.getSendBufferSize());
            } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
                return Integer.valueOf(socket.getReceiveBufferSize());
            } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                return Boolean.valueOf(socket.getReuseAddress());
            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
            } else if (option.equals(StandardSocketOptions.SO_LINGER)) {
                return Integer.valueOf(socket.getSoLinger());
            } else if (option.equals(StandardSocketOptions.IP_TOS)) {
                return Integer.valueOf(socket.getTrafficClass());
            } else if (option.equals(StandardSocketOptions.TCP_NODELAY)) {
                return Boolean.valueOf(socket.getTcpNoDelay());
            } else {
                throw new RuntimeException("unexpected socket option");
            }
        } else if  (type.equals(ServerSocket.class)) {
            ServerSocket socket = (ServerSocket)s;
            Set<SocketOption<?>> options = socket.supportedOptions();
            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);

            if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
                return Integer.valueOf(socket.getReceiveBufferSize());
            } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                return Boolean.valueOf(socket.getReuseAddress());
            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
            } else if (option.equals(StandardSocketOptions.IP_TOS)) {
                return getServerSocketTrafficClass(socket);
            } else {
                throw new RuntimeException("unexpected socket option");
            }
        } else if  (type.equals(DatagramSocket.class)) {
            DatagramSocket socket = (DatagramSocket)s;
            Set<SocketOption<?>> options = socket.supportedOptions();
            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);

            if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
                return Integer.valueOf(socket.getSendBufferSize());
            } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
                return Integer.valueOf(socket.getReceiveBufferSize());
            } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                return Boolean.valueOf(socket.getReuseAddress());
            } else if (option.equals(StandardSocketOptions.SO_BROADCAST)) {
                return Boolean.valueOf(socket.getBroadcast());
            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
            } else if (option.equals(StandardSocketOptions.IP_TOS)) {
                return Integer.valueOf(socket.getTrafficClass());
            } else {
                throw new RuntimeException("unexpected socket option");
            }

        } else if  (type.equals(MulticastSocket.class)) {
            MulticastSocket socket = (MulticastSocket)s;
            Set<SocketOption<?>> options = socket.supportedOptions();
            boolean reuseport = options.contains(StandardSocketOptions.SO_REUSEPORT);

            if (option.equals(StandardSocketOptions.SO_SNDBUF)) {
                return Integer.valueOf(socket.getSendBufferSize());
            } else if (option.equals(StandardSocketOptions.SO_RCVBUF)) {
                return Integer.valueOf(socket.getReceiveBufferSize());
            } else if (option.equals(StandardSocketOptions.SO_REUSEADDR)) {
                return Boolean.valueOf(socket.getReuseAddress());
            } else if (option.equals(StandardSocketOptions.SO_BROADCAST)) {
                return Boolean.valueOf(socket.getBroadcast());
            } else if (option.equals(StandardSocketOptions.SO_REUSEPORT) && reuseport) {
                return Boolean.valueOf(socket.getOption(StandardSocketOptions.SO_REUSEPORT));
            } else if (option.equals(StandardSocketOptions.IP_TOS)) {
                return Integer.valueOf(socket.getTrafficClass());
            } else if (option.equals(StandardSocketOptions.IP_MULTICAST_IF)) {
                return socket.getNetworkInterface();
            } else if (option.equals(StandardSocketOptions.IP_MULTICAST_TTL)) {
                return Integer.valueOf(socket.getTimeToLive());
            } else if (option.equals(StandardSocketOptions.IP_MULTICAST_LOOP)) {
                return !Boolean.valueOf(socket.getLoopbackMode());
            } else {
                throw new RuntimeException("unexpected socket option");
            }
        }
        throw new RuntimeException("unexpected socket type");
    }

    public static void main(String args[]) throws Exception {
        IPSupport.throwSkippedExceptionIfNonOperational();
        doSocketTests();
        doServerSocketTests();
        doDatagramSocketTests();
        doMulticastSocketTests();
    }

    // Reflectively access jdk.net.Sockets.getOption so that the test can run
    // without the jdk.net module.
    static Object getServerSocketTrafficClass(ServerSocket ss) throws Exception {
        try {
            Class<?> c = Class.forName("jdk.net.Sockets");
            Method m = c.getMethod("getOption", ServerSocket.class, SocketOption.class);
            return m.invoke(null, ss, StandardSocketOptions.IP_TOS);
        } catch (ClassNotFoundException e) {
            // Ok, jdk.net module not present, just fall back
            System.out.println("jdk.net module not present, falling back.");
            return Integer.valueOf(ss.getOption(StandardSocketOptions.IP_TOS));
        } catch (ReflectiveOperationException e) {
            throw new AssertionError(e);
        }
    }
}
