/*
 * 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
 * @bug 4455376
 * @summary Ensure that socket objects obtained from channels
 *          carry the correct address information
 */

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


public class Shadow {

    private static final int PORT = 2019;
    static PrintStream log = System.err;

    private static void dump(ServerSocket s) {
        log.println("getInetAddress(): " + s.getInetAddress());
        log.println("getLocalPort(): " + s.getLocalPort());
    }

    private static void dump(Socket s) {
        log.println("getInetAddress(): " + s.getInetAddress());
        log.println("getPort(): " + s.getPort());
        log.println("getLocalAddress(): " + s.getLocalAddress());
        log.println("getLocalPort(): " + s.getLocalPort());
    }

    private static int problems = 0;

    private static void problem(String s) {
        log.println("FAILURE: " + s);
        problems++;
    }

    private static void check(Socket s) {
        if (s.getPort() == 0)
            problem("Socket has no port");
        if (s.getLocalPort() == 0)
            problem("Socket has no local port");
        if (!s.getLocalAddress().equals(s.getInetAddress()))
            problem("Socket has wrong local address");
    }

    public static void main(String[] args) throws Exception {
        boolean useChannels
            = ((args.length == 0) || Boolean.valueOf(args[0]).booleanValue());
        int port = (args.length > 1 ? Integer.parseInt(args[1]) : PORT);

        // open server socket
        ServerSocket serverSocket;
        if (useChannels) {
            ServerSocketChannel serverSocketChannel =
                ServerSocketChannel.open();
            log.println("opened ServerSocketChannel: " +
                      serverSocketChannel);
            serverSocket = serverSocketChannel.socket();
            log.println("associated ServerSocket: " + serverSocket);
        } else {
            serverSocket = new ServerSocket();
            log.println("opened ServerSocket: " + serverSocket);
        }

        // bind server socket to port
        SocketAddress bindAddr = new InetSocketAddress(port);
        serverSocket.bind(bindAddr);
        log.println("bound ServerSocket: " + serverSocket);

        log.println();

        // open client socket
        Socket socket;
        if (useChannels) {
            SocketChannel socketChannel = SocketChannel.open();
            log.println("opened SocketChannel: " + socketChannel);

            socket = socketChannel.socket();
            log.println("associated Socket: " + socket);
        } else {
            socket = new Socket();
            log.println("opened Socket: " + socket);
        }

        // connect client socket to port
        SocketAddress connectAddr =
            new InetSocketAddress("127.0.0.1",
                                  serverSocket.getLocalPort());
        socket.connect(connectAddr);
        log.println("connected Socket: " + socket);

        log.println();

        // accept connection
        Socket acceptedSocket = serverSocket.accept();
        log.println("accepted Socket: " + acceptedSocket);

        log.println();
        log.println("========================================");

        log.println("*** ServerSocket info: ");
        dump(serverSocket);
        log.println();

        log.println("*** client Socket info: ");
        dump(socket);
        check(socket);
        log.println();

        log.println("*** accepted Socket info: ");
        dump(acceptedSocket);
        check(acceptedSocket);
        log.println();

        if (problems > 0)
            throw new Exception(problems + " tests failed");
    }

}
