package com.yahoo.io;

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

import org.junit.Test;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;

/**
 * @author arnej
 */
public class TeeInputStreamTest {

    @Test
    public void testSimpleInput() throws IOException {
        byte[] input = "very simple input".getBytes(StandardCharsets.UTF_8);
        ByteArrayInputStream in = new ByteArrayInputStream(input);
        ByteArrayOutputStream gotten = new ByteArrayOutputStream();

        TeeInputStream tee = new TeeInputStream(in, gotten);
        int b = tee.read();
        assertThat(b, is((int)'v'));
        assertThat(gotten.toString(), is("very simple input"));
        for (int i = 0; i < 16; i++) {
            b = tee.read();
            // System.out.println("got["+i+"]: "+(char)b);
            assertThat(b, is(greaterThan(0)));
        }
        assertThat(tee.read(), is(-1));
    }

    private class Generator implements Runnable {
        private OutputStream dst;
        public Generator(OutputStream dst) { this.dst = dst; }
        @Override
        public void run() {
            for (int i = 0; i < 123456789; i++) {
                int b = i & 0x7f;
                if (b < 32) continue;
                if (b > 126) b = '\n';
                try {
                    dst.write(b);
                } catch (IOException e) {
                    return;
                }
            }
        }
    }

    @Test
    public void testPipedInput() throws IOException {
        PipedOutputStream input = new PipedOutputStream();
        PipedInputStream in = new PipedInputStream(input);
        ByteArrayOutputStream gotten = new ByteArrayOutputStream();
        TeeInputStream tee = new TeeInputStream(in, gotten);
        input.write("first input".getBytes(StandardCharsets.UTF_8));
        int b = tee.read();
        assertThat(b, is((int)'f'));
        assertThat(gotten.toString(), is("first input"));
        input.write(" second input".getBytes(StandardCharsets.UTF_8));
        b = tee.read();
        assertThat(b, is((int)'i'));
        assertThat(gotten.toString(), is("first input second input"));
        new Thread(new Generator(input)).start();
        b = tee.read();
        assertThat(b, is((int)'r'));
        byte[] ba = new byte[9];
        for (int i = 0; i < 12345; i++) {
            b = tee.read();
            // System.out.println("got["+i+"]: "+(char)b);
            assertThat(b, is(greaterThan(0)));
            assertThat(tee.read(ba), is(greaterThan(0)));
        }
        tee.close();
        String got = gotten.toString();
        // System.out.println("got length: "+got.length());
        // System.out.println("got: "+got);
        assertThat(got.length(), is(greaterThan(34567)));
    }

}

@@ -559,16 +559,84 @@
 tream();
+%0A        ByteArrayOutputStream output = new ByteArrayOutputStream();
 %0A%0A      
@@ -751,24 +751,49 @@
 (int)'v'));%0A
+        output.write(b);%0A
         asse
@@ -1009,32 +1009,61 @@
 eaterThan(0)));%0A
+            output.write(b);%0A
         %7D%0A      
@@ -1092,24 +1092,152 @@
 ), is(-1));%0A
+        assertThat(gotten.toString(), is(%22very simple input%22));%0A        assertThat(output.toString(), is(%22very simple input%22));%0A
     %7D%0A%0A    p
@@ -2002,32 +2002,100 @@
 OutputStream();%0A
+        ByteArrayOutputStream output = new ByteArrayOutputStream();%0A
         TeeInput
@@ -2269,24 +2269,49 @@
 (int)'f'));%0A
+        output.write(b);%0A
         asse
@@ -2484,24 +2484,49 @@
 (int)'i'));%0A
+        output.write(b);%0A
         asse
@@ -2691,24 +2691,49 @@
 (int)'r'));%0A
+        output.write(b);%0A
         byte
@@ -2945,51 +2945,258 @@
     
-assertThat(tee.read(ba), is(greaterThan(0))
+output.write(b);%0A            int l = tee.read(ba);%0A            assertThat(l, is(greaterThan(0)));%0A            output.write(ba, 0, l);%0A            l = tee.read(ba, 3, 3);%0A            assertThat(l, is(greaterThan(0)));%0A            output.write(ba, 3, l
 );%0A 
@@ -3321,24 +3321,101 @@
 .length());%0A
+        // System.out.println(%22output length: %22+output.toString().length());%0A
         // S
@@ -3500,21 +3500,76 @@
 n(34567)));%0A
+        assertTrue(got.startsWith(output.toString()));%0A
     %7D%0A%0A%7D%0A

improve test after review