/*
 * Copyright 2009 Google, 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 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 4206909 4813885
 * @summary Test basic functionality of DeflaterOutputStream/InflaterInputStream and GZIPOutputStream/GZIPInputStream, including flush
 */

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

public class InflateIn_DeflateOut {

    private static class PairedInputStream extends ByteArrayInputStream {
        private PairedOutputStream out = null;
        private Random random;

        public PairedInputStream() {
            // The ByteArrayInputStream needs to start with a buffer, but we
            // need to set it to have no data
            super(new byte[1]);
            count = 0;
            pos = 0;
            random = new Random(new Date().getTime());
        }

        public void setPairedOutputStream(PairedOutputStream out) {
            this.out = out;
        }

        private void maybeFlushPair() {
            if (random.nextInt(100) < 10) {
                out.flush();
            }
        }

        public int read() {
            maybeFlushPair();
            return super.read();
        }

        public int read(byte b[], int off, int len) {
            maybeFlushPair();
            return super.read(b, off, len);
        }

        public void addBytes(byte[] bytes, int len) {
            int oldavail = count - pos;
            int newcount = oldavail + len;
            byte[] newbuf = new byte[newcount];
            System.arraycopy(buf, pos, newbuf, 0, oldavail);
            System.arraycopy(bytes, 0, newbuf, oldavail, len);
            pos = 0;
            count = newcount;
            buf = newbuf;
        }
    }

    private static class PairedOutputStream extends ByteArrayOutputStream {
        private PairedInputStream pairedStream = null;

        public PairedOutputStream(PairedInputStream inputPair) {
            super();
            this.pairedStream = inputPair;
        }

        public void flush() {
            if (count > 0) {
                pairedStream.addBytes(buf, count);
                reset();
            }
        }

        public void close() {
            flush();
        }
    }

    private static boolean readFully(InputStream in, byte[] buf, int length)
            throws IOException {
        int pos = 0;
        int n;
        while ((n = in.read(buf, pos, length - pos)) > 0) {
            pos += n;
            if (pos == length) return true;
        }
        return false;
    }

    private static boolean readLineIfAvailable(InputStream in, StringBuilder sb)
            throws IOException {
        try {
            while (in.available() > 0) {
                int i = in.read();
                if (i < 0) break;
                char c = (char) (((byte) i) & 0xff);
                sb.append(c);
                if (c == '\n') return true;
            }
        } catch (EOFException e) {
          // empty
        }
        return false;
    }

    /** Check that written, closed and read */
    private static void WriteCloseRead() throws Throwable {
        Random random = new Random(new Date().getTime());

        PairedInputStream pis = new PairedInputStream();
        InflaterInputStream iis = new InflaterInputStream(pis);

        PairedOutputStream pos = new PairedOutputStream(pis);
        pis.setPairedOutputStream(pos);

        byte[] data = new byte[random.nextInt(1024 * 1024)];
        byte[] buf = new byte[data.length];
        random.nextBytes(data);

        try (DeflaterOutputStream dos = new DeflaterOutputStream(pos, true)) {
            dos.write(data);
        }
        check(readFully(iis, buf, buf.length));
        check(Arrays.equals(data, buf));
    }

    private static void check(InputStream is, OutputStream os)
        throws Throwable
    {
        Random random = new Random(new Date().getTime());
       // Large writes
        for (int x = 0; x < 200 ; x++) {
            // byte[] data = new byte[random.nextInt(1024 * 1024)];
            byte[] data = new byte[1024];
            byte[] buf = new byte[data.length];
            random.nextBytes(data);

            os.write(data);
            os.flush();
            check(readFully(is, buf, buf.length));
            check(Arrays.equals(data, buf));
        }

        // Small writes
        for (int x = 0; x < 2000 ; x++) {
            byte[] data = new byte[random.nextInt(20) + 10];
            byte[] buf = new byte[data.length];
            random.nextBytes(data);

            os.write(data);
            os.flush();
            if (!readFully(is, buf, buf.length)) {
                fail("Didn't read full buffer of " + buf.length);
            }
            check(Arrays.equals(data, buf));
        }

        String quit = "QUIT\r\n";

        // Close it out
        os.write(quit.getBytes());
        os.close();

        StringBuilder sb = new StringBuilder();
        check(readLineIfAvailable(is, sb));
        equal(sb.toString(), quit);
    }

    /** Check that written, flushed and read */
    private static void WriteFlushRead() throws Throwable {
        PairedInputStream pis = new PairedInputStream();
        InflaterInputStream iis = new InflaterInputStream(pis);

        PairedOutputStream pos = new PairedOutputStream(pis);
        pis.setPairedOutputStream(pos);
        DeflaterOutputStream dos = new DeflaterOutputStream(pos, true);

        check(iis, dos);
    }

    private static void GZWriteFlushRead() throws Throwable {
        PairedInputStream pis = new PairedInputStream();
        PairedOutputStream pos = new PairedOutputStream(pis);
        pis.setPairedOutputStream(pos);

        GZIPOutputStream gos = new GZIPOutputStream(pos, true);
        gos.flush();  // flush the head out, so gis can read
        GZIPInputStream gis = new GZIPInputStream(pis);

        check(gis, gos);
    }

    private static void checkLOP(InputStream is, OutputStream os)
        throws Throwable
    {
        boolean flushed = false;
        int count = 0;

        // Do at least a certain number of lines, but too many without a
        // flush means this test isn't testing anything
        while ((count < 10 && flushed) || (count < 1000 && !flushed)) {
            String command = "PING " + count + "\r\n";
            os.write(command.getBytes());

            StringBuilder buf = new StringBuilder();
            if (!readLineIfAvailable(is, buf)) {
                flushed = true;
                os.flush();
                check(readLineIfAvailable(is, buf));
            }
            equal(buf.toString(), command);
            count++;
        }
        check(flushed);
    }

    /** Validate that we need to use flush at least once on a line
     * oriented protocol */
    private static void LineOrientedProtocol() throws Throwable {
        PairedInputStream pis = new PairedInputStream();
        InflaterInputStream iis = new InflaterInputStream(pis);

        PairedOutputStream pos = new PairedOutputStream(pis);
        pis.setPairedOutputStream(pos);
        DeflaterOutputStream dos = new DeflaterOutputStream(pos, true);

        checkLOP(iis, dos);
    }

    private static void GZLineOrientedProtocol() throws Throwable {
        PairedInputStream pis = new PairedInputStream();
        PairedOutputStream pos = new PairedOutputStream(pis);
        pis.setPairedOutputStream(pos);

        GZIPOutputStream gos = new GZIPOutputStream(pos, true);
        gos.flush();  // flush the head out, so gis can read
        GZIPInputStream gis = new GZIPInputStream(pis);

        checkLOP(gis, gos);
    }

    public static void realMain(String[] args) throws Throwable {
        WriteCloseRead();
        WriteFlushRead();
        LineOrientedProtocol();
        GZWriteFlushRead();
        GZLineOrientedProtocol();
    }

    //--------------------- Infrastructure ---------------------------
    static volatile int passed = 0, failed = 0;
    static void pass() {passed++;}
    static void fail() {failed++; Thread.dumpStack();}
    static void fail(String msg) {System.out.println(msg); fail();}
    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
    static void check(boolean cond) {if (cond) pass(); else fail();}
    static void equal(Object x, Object y) {
        if (x == null ? y == null : x.equals(y)) pass();
        else fail(x + " not equal to " + y);}
    public static void main(String[] args) throws Throwable {
        try {realMain(args);} catch (Throwable t) {unexpected(t);}
        System.out.println("\nPassed = " + passed + " failed = " + failed);
        if (failed > 0) throw new AssertionError("Some tests failed");}
}
