/*
 * Copyright (c) 2012, 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 utility classes
 *
 */

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import jdk.test.lib.Utils;


public class TestServers {

    private TestServers() { }

    /**
     * An abstract server identifies a server which listens on a port on a
     * given machine.
     */
    static abstract class AbstractServer {

        private AbstractServer() {
        }

        public abstract int getPort();

        public abstract InetAddress getAddress();
    }

    /**
     * A downgraded type of AbstractServer which will refuse connections. Note:
     * use it once and throw it away - this implementation opens an anonymous
     * socket and closes it, returning the address of the closed socket. If
     * other servers are started afterwards, the address/port might get reused
     * and become connectable again - so it's not a good idea to assume that
     * connections using this address/port will always be refused. Connections
     * will be refused as long as the address/port of the refusing server has
     * not been reused.
     */
    static class RefusingServer extends AbstractServer {

        final InetAddress address;
        final int port;

        private RefusingServer(InetAddress address, int port) {
            this.address = address;
            this.port = port;
        }

        @Override
        public int getPort() {
            return port;
        }

        @Override
        public InetAddress getAddress() {
            return address;
        }

        public static RefusingServer newRefusingServer() throws IOException {
            return new RefusingServer(InetAddress.getLocalHost(),
                       Utils.refusingEndpoint().getPort());
        }
    }

    /**
     * An abstract class for implementing small TCP servers for the nio tests
     * purposes. Disclaimer: This is a naive implementation that uses the old
     * networking APIs (not those from {@code java.nio.*}) and shamelessly
     * extends/creates Threads instead of using an executor service.
     */
    static abstract class AbstractTcpServer extends AbstractServer
            implements Runnable, Closeable {

        protected final long linger; // #of ms to wait before responding
        private Thread acceptThread; // thread waiting for accept
        // list of opened connections that should be closed on close.
        private List<TcpConnectionThread> connections = new ArrayList<>();
        private ServerSocket serverSocket; // the server socket
        private boolean started = false; // whether the server is started
        Throwable error = null;

        /**
         * Creates a new abstract TCP server.
         *
         * @param linger the amount of time the server should wait before
         * responding to requests.
         */
        protected AbstractTcpServer(long linger) {
            this.linger = linger;
        }

        /**
         * The local port to which the server is bound.
         *
         * @return The local port to which the server is bound.
         * @exception IllegalStateException is thrown if the server is not
         * started.
         */
        @Override
        public final synchronized int getPort() {
            if (!started) {
                throw new IllegalStateException("Not started");
            }
            return serverSocket.getLocalPort();
        }

        /**
         * The local address to which the server is bound.
         *
         * @return The local address to which the server is bound.
         * @exception IllegalStateException is thrown if the server is not
         * started.
         */
        @Override
        public final synchronized InetAddress getAddress() {
            if (!started) {
                throw new IllegalStateException("Not started");
            }
            return serverSocket.getInetAddress();
        }

        /**
         * Tells whether the server is started.
         *
         * @return true if the server is started.
         */
        public final synchronized boolean isStarted() {
            return started;
        }

        /**
         * Creates a new server socket.
         *
         * @param port local port to bind to.
         * @param backlog requested maximum length of the queue of incoming
         * connections.
         * @param address local address to bind to.
         * @return a new bound server socket ready to accept connections.
         * @throws IOException if the socket cannot be created or bound.
         */
        protected ServerSocket newServerSocket(int port, int backlog,
                InetAddress address)
                throws IOException {
            return new ServerSocket(port, backlog, address);
        }

        /**
         * Starts listening for connections.
         *
         * @throws IOException if the server socket cannot be created or bound.
         */
        public final synchronized void start() throws IOException {
            if (started) {
                return;
            }
            final ServerSocket socket =
                    newServerSocket(0, 100, InetAddress.getLocalHost());
            serverSocket = socket;
            acceptThread = new Thread(this);
            acceptThread.setDaemon(true);
            acceptThread.start();
            started = true;
        }

        /**
         * Calls {@code Thread.sleep(linger);}
         */
        protected final void lingerIfRequired() {
            if (linger > 0) {
                try {
                    Thread.sleep(linger);
                } catch (InterruptedException x) {
                    Thread.interrupted();
                    final ServerSocket socket = serverSocket();
                    if (socket != null && !socket.isClosed()) {
                        System.err.println("Thread interrupted...");
                    }
                }
            }
        }

        final synchronized ServerSocket serverSocket() {
            return this.serverSocket;
        }

        /**
         * The main accept loop.
         */
        @Override
        public final void run() {
            final ServerSocket sSocket = serverSocket();
            try {
                Socket s;
                while (isStarted() && !Thread.interrupted()
                        && (s = sSocket.accept()) != null) {
                    lingerIfRequired();
                    listen(s);
                }
            } catch (Exception x) {
                error = x;
            } finally {
                synchronized (this) {
                    if (!sSocket.isClosed()) {
                        try {
                            sSocket.close();
                        } catch (IOException x) {
                            System.err.println("Failed to close server socket");
                        }
                    }
                    if (started && this.serverSocket == sSocket) {
                        started = false;
                        this.serverSocket = null;
                        this.acceptThread = null;
                    }
                }
            }
        }

        /**
         * Represents a connection accepted by the server.
         */
        protected abstract class TcpConnectionThread extends Thread {

            protected final Socket socket;

            protected TcpConnectionThread(Socket socket) {
                this.socket = socket;
                this.setDaemon(true);
            }

            public void close() throws IOException {
                socket.close();
                interrupt();
            }
        }

        /**
         * Creates a new TcpConnnectionThread to handle the connection through
         * an accepted socket.
         *
         * @param s the socket returned by {@code serverSocket.accept()}.
         * @return a new TcpConnnectionThread to handle the connection through
         * an accepted socket.
         */
        protected abstract TcpConnectionThread createConnection(Socket s);

        /**
         * Creates and starts a new TcpConnectionThread to handle the accepted
         * socket.
         *
         * @param s the socket returned by {@code serverSocket.accept()}.
         */
        private synchronized void listen(Socket s) {
            TcpConnectionThread c = createConnection(s);
            c.start();
            addConnection(c);
        }

        /**
         * Add the connection to the list of accepted connections.
         *
         * @param connection an accepted connection.
         */
        protected synchronized void addConnection(
                TcpConnectionThread connection) {
            connections.add(connection);
        }

        /**
         * Remove the connection from the list of accepted connections.
         *
         * @param connection an accepted connection.
         */
        protected synchronized void removeConnection(
                TcpConnectionThread connection) {
            connections.remove(connection);
        }

        /**
         * Close the server socket and all the connections present in the list
         * of accepted connections.
         *
         * @throws IOException
         */
        @Override
        public synchronized void close() throws IOException {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
            if (acceptThread != null) {
                acceptThread.interrupt();
            }
            int failed = 0;
            for (TcpConnectionThread c : connections) {
                try {
                    c.close();
                } catch (IOException x) {
                    // no matter - we're closing.
                    failed++;
                }
            }
            connections.clear();
            if (failed > 0) {
                throw new IOException("Failed to close some connections");
            }
        }
    }

    /**
     * A small TCP Server that emulates the echo service for tests purposes. See
     * http://en.wikipedia.org/wiki/Echo_Protocol This server uses an anonymous
     * port - NOT the standard port 7. We don't guarantee that its behavior
     * exactly matches the RFC - the only purpose of this server is to have
     * something that responds to nio tests...
     */
    static class EchoServer extends AbstractTcpServer {

        public EchoServer() {
            this(0L);
        }

        public EchoServer(long linger) {
            super(linger);
        }

        @Override
        protected TcpConnectionThread createConnection(Socket s) {
            return new EchoConnection(s);
        }

        private final class EchoConnection extends TcpConnectionThread {

            public EchoConnection(Socket socket) {
                super(socket);
            }

            @Override
            public void run() {
                try {
                    final InputStream is = socket.getInputStream();
                    final OutputStream out = socket.getOutputStream();
                    byte[] b = new byte[255];
                    int n;
                    while ((n = is.read(b)) > 0) {
                        lingerIfRequired();
                        out.write(b, 0, n);
                    }
                } catch (IOException io) {
                    // fall through to finally
                } finally {
                    if (!socket.isClosed()) {
                        try {
                            socket.close();
                        } catch (IOException x) {
                            System.err.println(
                                    "Failed to close echo connection socket");
                        }
                    }
                    removeConnection(this);
                }
            }
        }

        public static EchoServer startNewServer() throws IOException {
            return startNewServer(0);
        }

        public static EchoServer startNewServer(long linger) throws IOException {
            final EchoServer echoServer = new EchoServer(linger);
            echoServer.start();
            return echoServer;
        }
    }

    /**
     * A small TCP Server that accept connections but does not response to any input.
     */
    static final class NoResponseServer extends EchoServer {
        public NoResponseServer() {
            super(Long.MAX_VALUE);
        }

        public static NoResponseServer startNewServer() throws IOException {
            final NoResponseServer noResponseServer = new NoResponseServer();
            noResponseServer.start();
            return noResponseServer;
        }
    }

    /**
     * A small TCP server that emulates the Day & Time service for tests
     * purposes. See http://en.wikipedia.org/wiki/Daytime_Protocol This server
     * uses an anonymous port - NOT the standard port 13. We don't guarantee
     * that its behavior exactly matches the RFC - the only purpose of this
     * server is to have something that responds to nio tests...
     */
    static final class DayTimeServer extends AbstractTcpServer {

        public DayTimeServer() {
            this(0L);
        }

        public DayTimeServer(long linger) {
            super(linger);
        }

        @Override
        protected TcpConnectionThread createConnection(Socket s) {
            return new DayTimeServerConnection(s);
        }

        @Override
        protected void addConnection(TcpConnectionThread connection) {
            // do nothing - the connection just write the date and terminates.
        }

        @Override
        protected void removeConnection(TcpConnectionThread connection) {
            // do nothing - we're not adding connections to the list...
        }

        private final class DayTimeServerConnection extends TcpConnectionThread {

            public DayTimeServerConnection(Socket socket) {
                super(socket);
            }

            @Override
            public void run() {
                try {
                    final OutputStream out = socket.getOutputStream();
                    lingerIfRequired();
                    out.write(new Date(System.currentTimeMillis())
                            .toString().getBytes("US-ASCII"));
                    out.flush();
                } catch (IOException io) {
                    // fall through to finally
                } finally {
                    if (!socket.isClosed()) {
                        try {
                            socket.close();
                        } catch (IOException x) {
                            System.err.println(
                                    "Failed to close echo connection socket");
                        }
                    }
                }
            }
        }

        public static DayTimeServer startNewServer()
                throws IOException {
            return startNewServer(0);
        }

        public static DayTimeServer startNewServer(long linger)
                throws IOException {
            final DayTimeServer daytimeServer = new DayTimeServer(linger);
            daytimeServer.start();
            return daytimeServer;
        }
    }

    /**
     * An abstract class for implementing small UDP Servers for the nio tests
     * purposes. Disclaimer: This is a naive implementation that uses the old
     * networking APIs (not those from {@code java.nio.*}) and shamelessly
     * extends/creates Threads instead of using an executor service.
     */
    static abstract class AbstractUdpServer extends AbstractServer
            implements Runnable, Closeable {

        protected final long linger; // #of ms to wait before responding
        protected final InetAddress bindAddress; //local address to bind to; can be null.
        private Thread acceptThread; // thread waiting for packets
        private DatagramSocket serverSocket; // the server socket
        private boolean started = false; // whether the server is started
        Throwable error = null;

        /**
         * Creates a new abstract UDP server.
         *
         * @param linger the amount of time the server should wait before
         * responding to requests.
         */
        protected AbstractUdpServer(long linger) {
            this(linger, null);
        }

        /**
         * Creates a new abstract UDP server.
         *
         * @param linger the amount of time the server should wait before
         *          responding to requests.
         * @param bindAddress the address to bind to. If {@code null}, will
         *                    bind to InetAddress.getLocalHost();
         */
        protected AbstractUdpServer(long linger, InetAddress bindAddress) {
            this.linger = linger;
            this.bindAddress = bindAddress;
        }

        /**
         * The local port to which the server is bound.
         *
         * @return The local port to which the server is bound.
         * @exception IllegalStateException is thrown if the server is not
         * started.
         */
        @Override
        public final synchronized int getPort() {
            if (!started) {
                throw new IllegalStateException("Not started");
            }
            return serverSocket.getLocalPort();
        }

        /**
         * The local address to which the server is bound.
         *
         * @return The local address to which the server is bound.
         * @exception IllegalStateException is thrown if the server is not
         * started.
         */
        @Override
        public final synchronized InetAddress getAddress() {
            if (!started) {
                throw new IllegalStateException("Not started");
            }
            return serverSocket.getLocalAddress();
        }

        /**
         * Tells whether the server is started.
         *
         * @return true if the server is started.
         */
        public final synchronized boolean isStarted() {
            return started;
        }

        /**
         * Creates a new datagram socket.
         *
         * @param port local port to bind to.
         * @param address local address to bind to.
         * @return a new bound server socket ready to listen for packets.
         * @throws IOException if the socket cannot be created or bound.
         */
        protected DatagramSocket newDatagramSocket(int port,
                InetAddress address)
                throws IOException {
            return new DatagramSocket(port, address);
        }

        /**
         * Starts listening for connections.
         *
         * @throws IOException if the server socket cannot be created or bound.
         */
        public final synchronized void start() throws IOException {
            if (started) {
                return;
            }
            InetAddress lh = bindAddress == null ? InetAddress.getLocalHost() : bindAddress;
            final DatagramSocket socket =
                    newDatagramSocket(0, lh);
            serverSocket = socket;
            acceptThread = new Thread(this);
            acceptThread.setDaemon(true);
            acceptThread.start();
            started = true;
        }

        /**
         * Calls {@code Thread.sleep(linger);}
         */
        protected final void lingerIfRequired() {
            if (linger > 0) {
                try {
                    Thread.sleep(linger);
                } catch (InterruptedException x) {
                    Thread.interrupted();
                    final DatagramSocket socket = serverSocket();
                    if (socket != null && !socket.isClosed()) {
                        System.err.println("Thread interrupted...");
                    }
                }
            }
        }

        final synchronized DatagramSocket serverSocket() {
            return this.serverSocket;
        }

        final synchronized boolean send(DatagramSocket socket,
                DatagramPacket response) throws IOException {
            if (!socket.isClosed()) {
                socket.send(response);
                return true;
            } else {
                return false;
            }
        }

        /**
         * The main receive loop.
         */
        @Override
        public final void run() {
            final DatagramSocket sSocket = serverSocket();
            try {
                final int size = Math.max(1024, sSocket.getReceiveBufferSize());
                if (size > sSocket.getReceiveBufferSize()) {
                    sSocket.setReceiveBufferSize(size);
                }
                while (isStarted() && !Thread.interrupted() && !sSocket.isClosed()) {
                    final byte[] buf = new byte[size];
                    final DatagramPacket packet =
                            new DatagramPacket(buf, buf.length);
                    lingerIfRequired();
                    sSocket.receive(packet);
                    //System.out.println("Received packet from: "
                    //        + packet.getAddress()+":"+packet.getPort());
                    handle(sSocket, packet);
                }
            } catch (Exception x) {
                error = x;
            } finally {
                synchronized (this) {
                    if (!sSocket.isClosed()) {
                        sSocket.close();
                    }
                    if (started && this.serverSocket == sSocket) {
                        started = false;
                        this.serverSocket = null;
                        this.acceptThread = null;
                    }
                }
            }
        }

        /**
         * Represents an UDP request received by the server.
         */
        protected abstract class UdpRequestThread extends Thread {

            protected final DatagramPacket request;
            protected final DatagramSocket socket;

            protected UdpRequestThread(DatagramSocket socket, DatagramPacket request) {
                this.socket = socket;
                this.request = request;
                this.setDaemon(true);
            }
        }

        /**
         * Creates a new UdpRequestThread to handle a DatagramPacket received
         * through a DatagramSocket.
         *
         * @param socket the socket through which the request was received.
         * @param request the datagram packet received through the socket.
         * @return a new UdpRequestThread to handle the request received through
         * a DatagramSocket.
         */
        protected abstract UdpRequestThread createConnection(DatagramSocket socket,
                DatagramPacket request);

        /**
         * Creates and starts a new UdpRequestThread to handle the received
         * datagram packet.
         *
         * @param socket the socket through which the request was received.
         * @param request the datagram packet received through the socket.
         */
        private synchronized void handle(DatagramSocket socket,
                DatagramPacket request) {
            UdpRequestThread c = createConnection(socket, request);
            // c can be null if the request requires no response.
            if (c != null) {
                c.start();
            }
        }

        /**
         * Close the server socket.
         *
         * @throws IOException
         */
        @Override
        public synchronized void close() throws IOException {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
            if (acceptThread != null) {
                acceptThread.interrupt();
            }
        }
    }

    /**
     * A small UDP Server that emulates the discard service for tests purposes.
     * See http://en.wikipedia.org/wiki/Discard_Protocol This server uses an
     * anonymous port - NOT the standard port 9. We don't guarantee that its
     * behavior exactly matches the RFC - the only purpose of this server is to
     * have something that responds to nio tests...
     */
    static final class UdpDiscardServer extends AbstractUdpServer {

        public UdpDiscardServer() {
            this(0L);
        }

        public UdpDiscardServer(long linger) {
            super(linger);
        }

        @Override
        protected UdpRequestThread createConnection(DatagramSocket socket,
                DatagramPacket request) {
            // no response required
            return null;
        }

        public static UdpDiscardServer startNewServer() throws IOException {
            return startNewServer(0);
        }

        public static UdpDiscardServer startNewServer(long linger) throws IOException {
            final UdpDiscardServer discardServer = new UdpDiscardServer(linger);
            discardServer.start();
            return discardServer;
        }
    }

    /**
     * A small UDP Server that emulates the echo service for tests purposes. See
     * http://en.wikipedia.org/wiki/Echo_Protocol This server uses an anonymous
     * port - NOT the standard port 7. We don't guarantee that its behavior
     * exactly matches the RFC - the only purpose of this server is to have
     * something that responds to nio tests...
     */
    static final class UdpEchoServer extends AbstractUdpServer {

        public UdpEchoServer() {
            this(0L);
        }

        public UdpEchoServer(long linger) {
            this(linger, null);
        }

        public UdpEchoServer(long linger, InetAddress bindAddress) {
            super(linger, bindAddress);
        }

        @Override
        protected UdpEchoRequest createConnection(DatagramSocket socket,
                DatagramPacket request) {
            return new UdpEchoRequest(socket, request);
        }

        private final class UdpEchoRequest extends UdpRequestThread {

            public UdpEchoRequest(DatagramSocket socket, DatagramPacket request) {
                super(socket, request);
            }

            @Override
            public void run() {
                try {
                    lingerIfRequired();
                    final DatagramPacket response =
                            new DatagramPacket(request.getData(),
                                    request.getOffset(), request.getLength(),
                                    request.getAddress(), request.getPort());
                    send(socket, response);
                } catch (IOException io) {
                    System.err.println("Failed to send response: " + io);
                    io.printStackTrace(System.err);
                }
            }
        }

        public static UdpEchoServer startNewServer() throws IOException {
            return startNewServer(0);
        }

        public static UdpEchoServer startNewServer(long linger) throws IOException {
            return startNewServer(0, InetAddress.getLocalHost());
        }

        public static UdpEchoServer startNewServer(long linger, InetAddress bindAddress) throws IOException {
            final UdpEchoServer echoServer = new UdpEchoServer(linger, bindAddress);
            echoServer.start();
            return echoServer;
        }
    }

    /**
     * A small UDP server that emulates the Day & Time service for tests
     * purposes. See http://en.wikipedia.org/wiki/Daytime_Protocol This server
     * uses an anonymous port - NOT the standard port 13. We don't guarantee
     * that its behavior exactly matches the RFC - the only purpose of this
     * server is to have something that responds to nio tests...
     */
    static final class UdpDayTimeServer extends AbstractUdpServer {

        public UdpDayTimeServer() {
            this(0L);
        }

        public UdpDayTimeServer(long linger) {
            super(linger);
        }

        @Override
        protected UdpDayTimeRequestThread createConnection(DatagramSocket socket,
                DatagramPacket request) {
            return new UdpDayTimeRequestThread(socket, request);
        }

        private final class UdpDayTimeRequestThread extends UdpRequestThread {

            public UdpDayTimeRequestThread(DatagramSocket socket,
                    DatagramPacket request) {
                super(socket, request);
            }

            @Override
            public void run() {
                try {
                    lingerIfRequired();
                    final byte[] data = new Date(System.currentTimeMillis())
                            .toString().getBytes("US-ASCII");
                    final DatagramPacket response =
                            new DatagramPacket(data, 0, data.length,
                                    request.getAddress(), request.getPort());
                    send(socket, response);
                } catch (IOException io) {
                    System.err.println("Failed to send response: " + io);
                    io.printStackTrace(System.err);
                }
            }
        }

        public static UdpDayTimeServer startNewServer() throws IOException {
            return startNewServer(0);
        }

        public static UdpDayTimeServer startNewServer(long linger)
                throws IOException {
            final UdpDayTimeServer echoServer = new UdpDayTimeServer(linger);
            echoServer.start();
            return echoServer;
        }
    }
}
