/*
 * Copyright (c) 2006, 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 6373555
 * @summary HTTP Server failing to answer client requests
 */

import java.net.*;
import java.io.*;
import javax.xml.soap.*;
import java.util.*;
import com.sun.net.httpserver.*;
import java.util.concurrent.*;

public class B6373555 {

    private static int s_received = 0;
    private static int sent = 0;

    private static int received = 0;
    private static int port;

    private static volatile boolean error = false;
    private static Object lock;
    static HttpServer httpServer;
    static ExecutorService pool, execs;
    static int NUM = 4000;

    public static void main(String[] args) throws Exception {
        try {
            lock = new Object();
            if (args.length > 0) {
                NUM = Integer.parseInt (args[0]);
            }
            execs = Executors.newFixedThreadPool(5);
            httpServer = createHttpServer(execs);
            port = httpServer.getAddress().getPort();
            pool = Executors.newFixedThreadPool(10);
            httpServer.start();
            for (int i=0; i < NUM; i++) {
                pool.execute(new Client());
                if (error) {
                    throw new Exception ("error in test");
                }
            }
            System.out.println("Main thread waiting");
            pool.shutdown();
            long latest = System.currentTimeMillis() + 200 * 1000;
            while (System.currentTimeMillis() < latest) {
                if (pool.awaitTermination(2000L, TimeUnit.MILLISECONDS)) {
                    System.out.println("Main thread done!");
                    return;
                }
                if (error) {
                    throw new Exception ("error in test");
                }
            }
            throw new Exception ("error in test: timed out");
        } finally {
            httpServer.stop(0);
            pool.shutdownNow();
            execs.shutdownNow();
        }
    }

    public static class Client implements Runnable {

        byte[] getBuf () {
            byte[] buf = new byte [5200];
            for (int i=0; i< 5200; i++) {
                buf [i] = (byte)i;
            }
            return buf;
        }

        public void run() {
            try {
                Thread.sleep(10);
                byte[] buf = getBuf();
                URL url = new URL("http://127.0.0.1:"+port+"/test");
                HttpURLConnection con = (HttpURLConnection)url.openConnection();
                con.setDoOutput(true);
                con.setDoInput(true);
                con.setRequestMethod("POST");
                con.setRequestProperty(
                    "Content-Type",
                    "Multipart/Related; type=\"application/xop+xml\"; boundary=\"----=_Part_0_6251267.1128549570165\"; start-info=\"text/xml\"");
                OutputStream out = con.getOutputStream();
                out.write(buf);
                out.close();
                InputStream in = con.getInputStream();
                byte[] newBuf = readFully(in);
                in.close();
                if (buf.length != newBuf.length) {
                    System.out.println("Doesn't match");
                    error = true;
                }
                synchronized(lock) {
                    ++received;
                    if ((received % 1000) == 0) {
                        System.out.println("Received="+received);
                    }
                }
            }
            catch(Exception e) {
                //e.printStackTrace();
                System.out.print (".");
                error = true;
            }
        }
    }

    private static byte[] readFully(InputStream istream) throws IOException {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        byte[] buf = new byte[1024];
        int num = 0;

        if (istream != null) {
            while ((num = istream.read(buf)) != -1) {
                bout.write(buf, 0, num);
            }
        }
        byte[] ret = bout.toByteArray();
        return ret;
    }


    private static HttpServer createHttpServer(ExecutorService execs)
        throws Exception {
        InetSocketAddress inetAddress = new InetSocketAddress(0);
        HttpServer testServer = HttpServer.create(inetAddress, 5);
        testServer.setExecutor(execs);
        HttpContext context = testServer.createContext("/test");
        context.setHandler(new HttpHandler() {
            public void handle(HttpExchange msg) {
                try {
                    synchronized(lock) {
                        ++s_received;
                            if ((s_received % 1000) == 0) {
                            System.out.println("Received="+s_received);
                        }
                    }
                    String method = msg.getRequestMethod();
                        if (method.equals("POST")) {
                        InputStream is = msg.getRequestBody();
                            byte[] buf = readFully(is);
                            is.close();
                            writePostReply(msg, buf);
                    } else {
                        System.out.println("****** METHOD not handled ***** "+method);
                            System.out.println("Received="+s_received);
                    }
                    synchronized(lock) {
                        ++sent;
                            if ((sent % 1000) == 0) {
                            System.out.println("sent="+sent);
                        }
                    }
                }
                catch(Exception e) {
                    e.printStackTrace();
                }
                finally {
                    msg.close();
                }
            }
        }
        );
        return testServer;
    }

    private static void writePostReply(HttpExchange msg, byte[] buf)
        throws Exception {
        msg.getResponseHeaders().add("Content-Type", "text/xml");
        msg.sendResponseHeaders(200, buf.length);
        OutputStream out = msg.getResponseBody();
        out.write(buf);
        out.close();
    }

}
