/*
 * Copyright 2002 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
 * @bug 4650679
 * @summary Unit test for socket channels
 * @library ..
 */

import java.nio.*;
import java.nio.channels.*;
import java.net.*;
import java.util.*;

public class Connect {

    private static final long INCREMENTAL_DELAY = 30L * 1000L;

    public static void main(String args[]) throws Exception {
        test1(TestUtil.HOST);
        try {
            test1(TestUtil.REFUSING_HOST);
            throw new Exception("Refused connection throws no exception");
        } catch (ConnectException ce) {
            // Correct result
        }
    }

    static void test1(String hostname) throws Exception {
        Selector selector;
        SocketChannel sc;
        SelectionKey sk;
        InetSocketAddress isa = new InetSocketAddress(
            InetAddress.getByName (hostname), 80);
        sc = SocketChannel.open();
        sc.configureBlocking(false);

        selector = Selector.open();
        sk = sc.register(selector, SelectionKey.OP_CONNECT);
        if (sc.connect(isa)) {
            System.err.println("Connected immediately!");
            sc.close();
            selector.close();
            return;
        } else {
            ByteBuffer buf = ByteBuffer.allocateDirect(100);
            buf.asCharBuffer().put(new String(
                "The quick brown fox jumped over the lazy dog."
                ).toCharArray());
            buf.flip();
            long startTime = System.currentTimeMillis();
            while(true) {
                selector.select(INCREMENTAL_DELAY);
                Set selectedKeys = selector.selectedKeys();

                if(selectedKeys.isEmpty()) {
                    System.err.println("Elapsed time without response: " +
                                       (System.currentTimeMillis() -
                                        startTime) / 1000L + " seconds.");
                }
                else if(!selectedKeys.contains(sk))
                {
                    System.err.println("Got wrong event about selection key.");
                } else {
                    System.err.println("Got event for our selection key.");
                    if(sk.isConnectable()) {
                        if(sc.finishConnect()) {
                            if(sc.isConnected()) {
                                System.err.println("Successful connect.");
                                sk.interestOps(SelectionKey.OP_WRITE);
                                sc.write(buf);
                            } else {
                                System.err.println(
                                      "Finish connect completed incorrectly.");
                            }
                        } else {
                            System.err.println(
                     "key incorrectly indicated socket channel connectable.");
                        }
                    }
                    if(sk.isWritable() && (buf.remaining() > 0)) {
                        sc.write(buf);
                    }
                    if(buf.remaining() == 0) {
                        System.err.println(
                            "SUCCESS! buffer contents were sent.");
                        sc.close();
                        selector.close();
                        return;
                    }
                }
                selectedKeys.clear();
            }
        }
    }
}
