/*
 * Copyright 2002-2006 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       NoLaunchOptionTest.java
 *   @bug        4554734 4724714
 *   @summary    Test for -Xrunjdwp:[onthrow,onuncaught] suboptions require launch suboption
 *   @author     Tim Bell
 *
 *  @run compile -g NoLaunchOptionTest.java
 *  @build VMConnection
 *  @run main/othervm NoLaunchOptionTest
 */
public class NoLaunchOptionTest extends Object {
    private Process subprocess;
    private int subprocessStatus;
    private static final String CR = System.getProperty("line.separator");
    private static final int BUFFERSIZE = 4096;
    public static final int RETSTAT = 0;
    public static final int STDOUT = 1;
    public static final int STDERR = 2;

    /**
     * Run an arbitrary command and return the results to caller.
     *
     * @param an array of String containing the command
     *        to run and any flags or parameters to the command.
     *
     * @return completion status, stderr and stdout as array of String
     *  Look for:
     *    return status in result[NoLaunchOptionTest.RETSTAT]
     *    standard out in result[NoLaunchOptionTest.STDOUT]
     *    standard err in result[NoLaunchOptionTest.STDERR]
     *
     */
    public String[] run (String[] cmdStrings) {
        StringBuffer stdoutBuffer = new StringBuffer();
        StringBuffer stderrBuffer = new StringBuffer();

        System.out.print(CR + "runCommand method about to execute: ");
        for (int iNdx = 0; iNdx < cmdStrings.length; iNdx++) {
            System.out.print(" ");
            System.out.print(cmdStrings[iNdx]);
        }
        System.out.println(CR);
        try {
            Process process = Runtime.getRuntime().exec(cmdStrings);
            /*
             * Gather up the output of the subprocess using non-blocking
             * reads so we can get both the subprocess stdout and the
             * subprocess stderr without overfilling any buffers.
             */
            java.io.BufferedInputStream is =
                new java.io.BufferedInputStream(process.getInputStream());
            int isLen = 0;
            byte[] isBuf = new byte[BUFFERSIZE];

            java.io.BufferedInputStream es =
                new java.io.BufferedInputStream(process.getErrorStream());
            int esLen = 0;
            byte[] esBuf = new byte[BUFFERSIZE];

            do {
                isLen = is.read(isBuf);
                if (isLen > 0) {
                    stdoutBuffer.append(
                                        new String(isBuf, 0, isLen));
                }
                esLen = es.read(esBuf);
                if (esLen > 0) {
                    stderrBuffer.append(
                                        new String(esBuf, 0, esLen));
                }
            } while ((isLen > -1) || (esLen > -1));
            try {
                process.waitFor();
                subprocessStatus = process.exitValue();
                process = null;
            } catch(java.lang.InterruptedException e) {
                System.err.println("InterruptedException: " + e);
            }

        } catch(java.io.IOException ex) {
            System.err.println("IO error: " + ex);
        }
        String[] result =
            new String[] {
                Integer.toString(subprocessStatus),
                stdoutBuffer.toString(),
                stderrBuffer.toString()
        };

        System.out.println(CR + "--- Return code was: " +
                           CR + result[RETSTAT]);
        System.out.println(CR + "--- Return stdout was: " +
                           CR + result[STDOUT]);
        System.out.println(CR + "--- Return stderr was: " +
                           CR + result[STDERR]);

        return result;
    }

    public static void main(String[] args) throws Exception {
        String javaExe = System.getProperty("java.home") +
            java.io.File.separator + "bin" +
            java.io.File.separator + "java";
        String targetClass = "NotAClass";
        String cmds [] = {javaExe,
                          "-agentlib:jdwp=transport=dt_socket,address=8000," +
                          "onthrow=java.lang.ClassNotFoundException,suspend=n",
                          targetClass};
        NoLaunchOptionTest myTest = new NoLaunchOptionTest();
        String results [] = myTest.run(VMConnection.insertDebuggeeVMOptions(cmds));
        if ((results[RETSTAT].equals("1")) &&
            (results[STDERR].startsWith("ERROR:"))) {
            System.out.println("Test passed: status = 1 with warning messages " +
                               "is expected and normal for this test");
        } else {
            throw new Exception("Test failed: unspecified test failure");
        }
    }

}
