/*
 * Copyright (c) 2023, 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 8304182
 * @summary ChannelInputStream hangs in native method SocketDispatcher.read0
 */

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.Channels;
import java.nio.channels.Pipe;
import java.nio.channels.spi.SelectorProvider;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

// import org.apache.commons.io.IOUtils;

public class PipeHang {
    public static void main(String[] x) throws Exception
    {
        File tmpFile = File.createTempFile("foo", "bar");
        tmpFile.deleteOnExit();
        try (FileOutputStream fos = new FileOutputStream(tmpFile)) {
            byte[] oneK = new byte[1024];
            for (int i = 0; i < 35; i++)
                fos.write(oneK);
        }

        for (int i = 0; i < 200; i++) {
            SelectorProvider selectorProvider = SelectorProvider.provider();
            final Pipe pipe = selectorProvider.openPipe();
            final InputStream is = Channels.newInputStream(pipe.source());
            final OutputStream os = Channels.newOutputStream(pipe.sink());
            final int index = i + 1;

            new Thread(() -> {
                    try {
                        try {
                            Thread.sleep(200);
                        } catch (InterruptedException aE) {
                            throw new RuntimeException(aE);
                        }
                        try (
                             FileInputStream fis = new FileInputStream(tmpFile);
                             InputStream inputStream =
                             new BufferedInputStream(fis); os) {
                            // IOUtils.copy(inputStream, os);
                            inputStream.transferTo(os);
                        }
                        System.out.println("WRITTEN for iteration " + index);
                    } catch (IOException aE) {
                        throw new RuntimeException(aE);
                    }
            }).start();

            try (is) {
                final String output = new String(is.readAllBytes());
                System.out.println("READ for iteration" + index);
            }
        }
    }
} 
