/*
 * Copyright (c) 2001, 2021, 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 4417152 4481572 6248930 6725399 6884800 8220477 8275149
 * @summary Test Channels basic functionality
 */

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

public class Basic {

    static String message;

    static String encoding;

    static File blah;

    static int ITERATIONS = 500;

    public static void main(String[] args) throws Exception {
        message = "ascii data for a test";
        encoding = "ISO-8859-1";
        test();
        message = "\ucafe\ubabe\ucafe\ubabe\ucafe\ubabe";
        encoding = "UTF-8";
        test();
    }

    static void failNpeExpected() {
        throw new RuntimeException("Did not get the expected NullPointerException.");
    }

    private static void test() throws Exception {
        //Test if methods of Channels throw NPE with null argument(s)
        try {
            Channels.newInputStream((ReadableByteChannel)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newOutputStream((WritableByteChannel)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            ReadableByteChannel channel = Channels.newChannel((InputStream)null);
            failNpeExpected();
        } catch (NullPointerException ne) {}  // OK. As expected.

        try {
            WritableByteChannel channel = Channels.newChannel((OutputStream)null);
            failNpeExpected();
        } catch (NullPointerException ne) {}  // OK. As expected.

        WritableByteChannel wbc = new WritableByteChannel() {
            public int write(ByteBuffer src) { return 0; }
            public void close() throws IOException { }
            public boolean isOpen() { return true; }
        };

        ReadableByteChannel rbc = new ReadableByteChannel() {
            public int read(ByteBuffer dst) { return 0; }
            public void close() {}
            public boolean isOpen() { return true; }
        };

        try {
            Channels.newReader((ReadableByteChannel)null,
                               Charset.defaultCharset().newDecoder(),
                               -1);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newReader(rbc, (CharsetDecoder)null, -1);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newReader((ReadableByteChannel)null,
                               Charset.defaultCharset().name());
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newReader(rbc, (String)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}


        try {
            Channels.newReader(null, (String)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newReader(rbc, (Charset)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}


        try {
            Channels.newReader(null, (Charset)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter((WritableByteChannel)null,
                               Charset.defaultCharset().newEncoder(),
                               -1);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter(null, null, -1);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter(wbc, null, -1);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter((WritableByteChannel)null,
                               Charset.defaultCharset().name());
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter(wbc, (String)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter(null, (String)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter(wbc, (Charset)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            Channels.newWriter(null, (Charset)null);
            failNpeExpected();
        } catch (NullPointerException npe) {}

        try {
            blah = File.createTempFile("blah", null);

            testNewOutputStream(blah);
            readAndCheck(blah);
            blah.delete();

            writeOut(blah, ITERATIONS);
            testNewInputStream(blah);
            blah.delete();

            testNewChannelOut(blah);
            readAndCheck(blah);
            blah.delete();

            testNewChannelWriteAfterClose(blah);

            testNewChannelReadAfterClose(blah);
            blah.delete();

            writeOut(blah, ITERATIONS);
            testNewChannelIn(blah);
            test4481572(blah);
            blah.delete();

            testNewWriter(blah);
            readAndCheck(blah);
            blah.delete();

            writeOut(blah, ITERATIONS);
            testNewReader(blah);

            testNewWriterClose();
            testNewReaderClose();
        } finally {
            blah.delete();
        }
    }

    private static void readAndCheck(File blah) throws Exception {
        FileInputStream fis = new FileInputStream(blah);
        int messageSize = message.length() * ITERATIONS * 3 + 1;
        byte bb[] = new byte[messageSize];
        int bytesRead = 0;
        int totalRead = 0;
        while (bytesRead != -1) {
            totalRead += bytesRead;
            bytesRead = fis.read(bb, totalRead, messageSize - totalRead);
        }
        String result = new String(bb, 0, totalRead, encoding);
        int len = message.length();
        for (int i=0; i<ITERATIONS; i++) {
            String segment = result.substring(i++ * len, i * len);
            if (!segment.equals(message))
                throw new RuntimeException("Test failed");
        }
        fis.close();
    }

    private static void writeOut(File blah, int limit) throws Exception {
        FileOutputStream fos = new FileOutputStream(blah);
        for (int i=0; i<limit; i++)
            fos.write(message.getBytes(encoding));
        fos.close();
    }

    private static void testNewOutputStream(File blah) throws Exception {
        FileOutputStream fos = new FileOutputStream(blah);
        FileChannel fc = fos.getChannel();
        WritableByteChannel wbc = (WritableByteChannel)fc;
        OutputStream os = Channels.newOutputStream(wbc);
        for (int i=0; i<ITERATIONS; i++)
            os.write(message.getBytes(encoding));
        os.close();
        fos.close();
    }

    private static void testNewInputStream(File blah) throws Exception {
        FileInputStream fis = new FileInputStream(blah);
        FileChannel fc = fis.getChannel();
        InputStream is = Channels.newInputStream(fc);
        int messageSize = message.length() * ITERATIONS * 3 + 1;
        byte bb[] = new byte[messageSize];

        int bytesRead = 0;
        int totalRead = 0;
        while (bytesRead != -1) {
            totalRead += bytesRead;
            long rem = Math.min(fc.size() - totalRead, (long)Integer.MAX_VALUE);
            if (is.available() != (int)rem)
                throw new RuntimeException("available not useful or not maximally useful");
            bytesRead = is.read(bb, totalRead, messageSize - totalRead);
        }
        if (is.available() != 0)
           throw new RuntimeException("available() should return 0 at EOF");

        String result = new String(bb, 0, totalRead, encoding);
        int len = message.length();
        for (int i=0; i<ITERATIONS; i++) {
            String segment = result.substring(i++ * len, i * len);
            if (!segment.equals(message))
                throw new RuntimeException("Test failed");
        }
        is.close();
        fis.close();
    }

    private static void testNewChannelOut(File blah) throws Exception {
        ExtendedFileOutputStream fos = new ExtendedFileOutputStream(blah);
        WritableByteChannel wbc = Channels.newChannel(fos);

        for (int i=0; i<ITERATIONS; i++)
            wbc.write(ByteBuffer.wrap(message.getBytes(encoding)));
        wbc.close();
        fos.close();
    }

    private static void testNewChannelIn(File blah) throws Exception {
        ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
        ReadableByteChannel rbc = Channels.newChannel(fis);

        int messageSize = message.length() * ITERATIONS * 3;
        byte data[] = new byte[messageSize+1];
        ByteBuffer bb = ByteBuffer.wrap(data);

        try {
            rbc.read(bb.asReadOnlyBuffer());
            throw new RuntimeException("IllegalArgumentException not thrown");
        } catch (IllegalArgumentException expected) {
            // ignore it
        }

        int bytesRead = 0;
        int totalRead = 0;
        while (bytesRead != -1) {
            totalRead += bytesRead;
            bytesRead = rbc.read(bb);
        }

        String result = new String(data, 0, totalRead, encoding);
        int len = message.length();
        for (int i=0; i<ITERATIONS; i++) {
            String segment = result.substring(i++ * len, i * len);
            if (!segment.equals(message))
                throw new RuntimeException("Test failed");
        }
        rbc.close();
        fis.close();
    }

    private static void testNewChannelWriteAfterClose(File blah)
        throws Exception {
        try (ExtendedFileOutputStream fos =
            new ExtendedFileOutputStream(blah)) {
            WritableByteChannel wbc = Channels.newChannel(fos);

            wbc.close();
            try {
                wbc.write(ByteBuffer.allocate(0));
                throw new RuntimeException
                    ("No ClosedChannelException on WritableByteChannel::write");
            } catch (ClosedChannelException expected) {
            }
        }
    }

    private static void testNewChannelReadAfterClose(File blah)
        throws Exception {
        try (ExtendedFileInputStream fis = new ExtendedFileInputStream(blah)) {
            ReadableByteChannel rbc = Channels.newChannel(fis);

            rbc.close();
            try {
                rbc.read(ByteBuffer.allocate(0));
                throw new RuntimeException
                    ("No ClosedChannelException on ReadableByteChannel::read");
            } catch (ClosedChannelException expected) {
            }
        }
    }

    // Causes BufferOverflowException if bug 4481572 is present.
    private static void test4481572(File blah) throws Exception {
        ExtendedFileInputStream fis = new ExtendedFileInputStream(blah);
        ReadableByteChannel rbc = Channels.newChannel(fis);

        byte data[] = new byte[9000];
        ByteBuffer bb = ByteBuffer.wrap(data);

        int bytesRead = 1;
        int totalRead = 0;
        while (bytesRead > 0) {
            totalRead += bytesRead;
            bytesRead = rbc.read(bb);
        }
        rbc.close();
        fis.close();
    }

    private static void testNewWriter(File blah) throws Exception {
        FileOutputStream fos = new FileOutputStream(blah);
        WritableByteChannel wbc = (WritableByteChannel)fos.getChannel();
        Writer w = Channels.newWriter(wbc, encoding);
        char data[] = new char[40];
        message.getChars(0, message.length(), data, 0);
        for (int i=0; i<ITERATIONS; i++)
            w.write(data, 0, message.length());
        w.flush();
        w.close();
        fos.close();
    }

    private static void testNewReader(File blah) throws Exception {
        FileInputStream fis = new FileInputStream(blah);
        ReadableByteChannel rbc = (ReadableByteChannel)fis.getChannel();
        Reader r = Channels.newReader(rbc, encoding);

        int messageSize = message.length() * ITERATIONS;
        char data[] = new char[messageSize];

        int totalRead = 0;
        int charsRead = 0;
        while (totalRead < messageSize) {
            totalRead += charsRead;
            charsRead = r.read(data, totalRead, messageSize - totalRead);
        }
        String result = new String(data, 0, totalRead);
        int len = message.length();
        for (int i=0; i<ITERATIONS; i++) {
            String segment = result.substring(i++ * len, i * len);
            if (!segment.equals(message))
                throw new RuntimeException("Test failed");
        }
        r.close();
        fis.close();
    }

    private static void testNewWriterClose() throws Exception {
        Writer writer = null;
        try {
            WritableByteChannel channel = new WritableByteChannel() {
                @Override
                public int write(ByteBuffer src) throws IOException {
                    return 0;
                }

                @Override
                public boolean isOpen() {
                    return true;
                }

                @Override
                public void close() throws IOException {
                    throw new IOException();
                }
            };
            writer = Channels.newWriter(channel,
                StandardCharsets.UTF_8.newEncoder(), -1);
            writer.close();
        } catch (IOException ioe) {
            Exception theException = null;
            try {
                writer.write(1);
                writer.flush();
            } catch (Exception e) {
                theException = e;
            } finally {
                if (theException == null) {
                    throw new RuntimeException("IOException not thrown");
                } else if (!(theException instanceof IOException)) {
                    throw new RuntimeException("Exception not an IOException: "
                        + theException);
                } else {
                    String message = theException.getMessage();
                    if (!message.equals("Stream closed")) {
                        throw new RuntimeException("Unexpected message "
                            + message);
                    }
                }
            }
        }
    }

    private static void testNewReaderClose() throws Exception {
        Reader reader = null;
        try {
            ReadableByteChannel channel = new ReadableByteChannel() {
                @Override
                public int read(ByteBuffer dst) throws IOException {
                    dst.put((byte)7);
                    return 1;
                }

                @Override
                public boolean isOpen() {
                    return true;
                }

                @Override
                public void close() throws IOException {
                    throw new IOException();
                }
            };
            reader = Channels.newReader(channel,
                StandardCharsets.UTF_8.newDecoder(), -1);
            reader.close();
        } catch (IOException ioe) {
            Exception theException = null;
            try {
                reader.read();
            } catch (Exception e) {
                theException = e;
            } finally {
                if (theException == null) {
                    throw new RuntimeException("IOException not thrown");
                } else if (!(theException instanceof IOException)) {
                    throw new RuntimeException("Exception not an IOException: "
                        + theException);
                } else {
                    String message = theException.getMessage();
                    if (!message.equals("Stream closed")) {
                        throw new RuntimeException("Unexpected message "
                            + message);
                    }
                }
            }
        }
    }
}

class ExtendedFileInputStream extends java.io.FileInputStream {
    ExtendedFileInputStream(File file) throws FileNotFoundException {
        super(file);
    }
}

class ExtendedFileOutputStream extends java.io.FileOutputStream {
    ExtendedFileOutputStream(File file) throws FileNotFoundException {
        super(file);
    }
}
