/*
 * Copyright 2005 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 5092263
 * @summary GZIPInputStream o GZIPOutputStream === the identity stream
 * @author Martin Buchholz
*/

// To manually test for uncompressed streams larger than 2GB, do
// javac Accordion.java && java -server Accordion 3325349068
// javac Accordion.java && java -server Accordion 5470735564

import java.io.*;
import java.util.*;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class Accordion {
    private static void readFully(InputStream s, byte[] buf) throws Throwable {
        int pos = 0;
        int n;
        while ((n = s.read(buf, pos, buf.length-pos)) > 0)
            pos += n;
        if (pos != buf.length)
            throw new Exception("Unexpected EOF");
    }

    private static volatile Throwable trouble;

    public static void main(String[] args) throws Throwable {
        if (args.length > 1)
            throw new Exception("Usage: java Accordion [BYTES]");

        final long bytes = args.length == 0 ? 10001 : Long.parseLong(args[0]);
        final int bufsize = 1729;
        final long count = bytes/bufsize;
        final PipedOutputStream out = new PipedOutputStream();
        final PipedInputStream in = new PipedInputStream(out);
        final Random random = new Random();
        final byte[] data = new byte[1729];
        for (int i = 0; i < data.length; i++)
            data[i] = (byte)random.nextInt(255);
        System.out.println("count="+count);

        Thread compressor = new Thread() { public void run() {
            try {
                final GZIPOutputStream s = new GZIPOutputStream(out);
                for (long i = 0; i < count; i++)
                    s.write(data, 0, data.length);
                s.close();
            } catch (Throwable t) { trouble = t; }}};

        Thread uncompressor = new Thread() { public void run() {
            try {
                final GZIPInputStream s = new GZIPInputStream(in);
                final byte[] maybeBytes = new byte[data.length];
                for (long i = 0; i < count; i++) {
                    readFully(s, maybeBytes);
                    if (! Arrays.equals(data, maybeBytes))
                        throw new Exception("data corruption");
                }
                if (s.read(maybeBytes, 0, 1) > 0)
                    throw new Exception("Unexpected NON-EOF");
                s.close();
            } catch (Throwable t) { trouble = t; }}};

        compressor.start(); uncompressor.start();
        compressor.join();  uncompressor.join();

        if (trouble != null)
            throw trouble;
    }
}
