/*
 * Copyright (c) 2001, 2010, 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 4452020 4629048 4638365 4869859
 * @summary Test FileChannel scattering reads
 * @run main/othervm ScatteringRead
 */

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

public class ScatteringRead {

    private static final int NUM_BUFFERS = 3;

    private static final int BUFFER_CAP = 3;

    private static final int BIG_BUFFER_CAP = Integer.MAX_VALUE / 3 + 10;

    public static void main(String[] args) throws Exception {
        test1(); // for bug 4452020
        test2(); // for bug 4629048
        System.gc();

        // Test 3 proves that the system is capable of reading
        // more than MAX_INT bytes in one shot. But it is unsuitable
        // for automated testing because oftentimes less bytes are
        // read for various reasons, and this is allowed by the spec.
        // test3(); // for bug 4638365
    }

    private static void test1() throws Exception {
        ByteBuffer dstBuffers[] = new ByteBuffer[NUM_BUFFERS];
        for (int i=0; i<NUM_BUFFERS; i++)
            dstBuffers[i] = ByteBuffer.allocateDirect(BUFFER_CAP);
        File blah = File.createTempFile("blah1", null);
        blah.deleteOnExit();
        createTestFile(blah);

        FileInputStream fis = new FileInputStream(blah);
        FileChannel fc = fis.getChannel();

        byte expectedResult = -128;
        for (int k=0; k<20; k++) {
            long bytesRead = fc.read(dstBuffers);
            for (int i=0; i<NUM_BUFFERS; i++) {
                for (int j=0; j<BUFFER_CAP; j++) {
                    byte b = dstBuffers[i].get(j);
                    if (b != expectedResult++)
                        throw new RuntimeException("Test failed");
                }
                dstBuffers[i].flip();
            }
        }
        fis.close();
    }

    private static void createTestFile(File blah) throws Exception {
        FileOutputStream fos = new FileOutputStream(blah);
        for(int i=-128; i<128; i++)
            fos.write((byte)i);
        fos.flush();
        fos.close();
    }

    private static void test2() throws Exception {
        ByteBuffer dstBuffers[] = new ByteBuffer[2];
        for (int i=0; i<2; i++)
            dstBuffers[i] = ByteBuffer.allocateDirect(10);
        File blah = File.createTempFile("blah2", null);
        blah.deleteOnExit();
        FileOutputStream fos = new FileOutputStream(blah);
        for(int i=0; i<15; i++)
            fos.write((byte)92);
        fos.flush();
        fos.close();

        FileInputStream fis = new FileInputStream(blah);
        FileChannel fc = fis.getChannel();

        long bytesRead = fc.read(dstBuffers);
        if (dstBuffers[1].limit() != 10)
            throw new Exception("Scattering read changed buf limit.");
        fis.close();
    }

    private static void test3() throws Exception {
        // Only works on 64 bit Solaris
        String osName = System.getProperty("os.name");
        if (!osName.startsWith("SunOS"))
            return;
        String dataModel = System.getProperty("sun.arch.data.model");
        if (!dataModel.startsWith("64"))
            return;

        ByteBuffer dstBuffers[] = new ByteBuffer[NUM_BUFFERS];
        File f = File.createTempFile("test3", null);
        f.deleteOnExit();
        prepTest3File(f, (long)BIG_BUFFER_CAP);
        RandomAccessFile raf = new RandomAccessFile(f, "rw");
        FileChannel fc = raf.getChannel();
        MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0,
                                      BIG_BUFFER_CAP);
        for (int i=0; i<NUM_BUFFERS; i++) {
            dstBuffers[i] = mbb;
        }
        fc.close();
        raf.close();

        // Source must be large
        FileInputStream fis = new FileInputStream("/dev/zero");
        fc = fis.getChannel();

        long bytesRead = fc.read(dstBuffers);
        if (bytesRead <= Integer.MAX_VALUE)
            throw new RuntimeException("Test 3 failed "+bytesRead+" < "+Integer.MAX_VALUE);

        fc.close();
        fis.close();
    }

    static void prepTest3File(File blah, long testSize) throws Exception {
        RandomAccessFile raf = new RandomAccessFile(blah, "rw");
        FileChannel fc = raf.getChannel();
        fc.write(ByteBuffer.wrap("Use the source!".getBytes()), testSize - 40);
        fc.close();
        raf.close();
    }

}
