/*
 * Copyright 2001 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/* @test
 * @summary Unit test for server-socket-channel adaptors
 */

import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;


public class AdaptServerSocket {

    static java.io.PrintStream out = System.out;

    static volatile Exception clientException = null;
    static volatile Thread client = null;

    static void startClient(final int port, final int dally)
        throws Exception
    {
        Thread t = new Thread() {
                public void run() {
                    try {
                        Socket so = new Socket();
                        out.println("client:  " + so);
                        if (dally > 0)
                            Thread.sleep(dally);
                        so.connect(new InetSocketAddress(port));
                        if (Thread.interrupted()) {
                            out.println("client interrupted");
                            so.close();
                            return;
                        }
                        out.println("client:  " + so);
                        int a = so.getInputStream().read();
                        out.println("client:  read " + a);
                        a += 1;
                        so.getOutputStream().write(a);
                        out.println("client:  wrote " + a);
                        so.close();
                    } catch (Exception x) {
                        if (x instanceof InterruptedException)
                            return;
                        clientException = x;
                        x.printStackTrace();
                    }
                }
            };
        t.setDaemon(true);
        t.start();
        client = t;
    }

    static void test(int clientDally, int timeout, boolean shouldTimeout)
        throws Exception
    {
        out.println();

        ServerSocketChannel ssc = ServerSocketChannel.open();
        ServerSocket sso = ssc.socket();
        out.println("created: " + ssc);
        out.println("         " + sso);
        if (timeout != 0)
            sso.setSoTimeout(timeout);
        out.println("timeout: " + sso.getSoTimeout());
        sso.bind(null);
        out.println("bound:   " + ssc);
        out.println("         " + sso);
        startClient(sso.getLocalPort(), clientDally);
        Thread.sleep(10);

        Socket so = null;
        try {
            so = sso.accept();
        } catch (SocketTimeoutException x) {
            if (shouldTimeout)
                out.println("Accept timed out, as expected");
            else
                throw x;
        }
        if (shouldTimeout && (so != null))
            throw new Exception("Accept did not time out");

        if (so != null) {
            int a = 42;
            so.getOutputStream().write(a);
            int b = so.getInputStream().read();
            if (b != a + 1)
                throw new Exception("Read incorrect data");
            out.println("server:  read " + b);
            sso.close();
        }

        client.interrupt();
        client.join();
        if (clientException != null)
            throw clientException;
    }

    public static void main(String[] args) throws Exception {
        test(0, 0, false);
        test(50, 500, false);
        test(500, 50, true);
    }

}
