/*
 * Copyright 2004-2007 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.
 */


/* DemoRun:
 *
 * Support classes for java jvmti demo tests
 *
 */

import java.io.InputStream;
import java.io.IOException;
import java.io.File;
import java.io.BufferedInputStream;
import java.io.PrintStream;

/*
 * Helper class to direct process output to a StringBuffer
 */
class MyInputStream implements Runnable {
    private String              name;
    private BufferedInputStream in;
    private StringBuffer        buffer;

    /* Create MyInputStream that saves all output to a StringBuffer */
    MyInputStream(String name, InputStream in) {
        this.name = name;
        this.in = new BufferedInputStream(in);
        buffer = new StringBuffer(4096);
        Thread thr = new Thread(this);
        thr.setDaemon(true);
        thr.start();
    }

    /* Dump the buffer */
    void dump(PrintStream x) {
        String str = buffer.toString();
        x.println("<beginning of " + name + " buffer>");
        x.println(str);
        x.println("<end of buffer>");
    }

    /* Check to see if a pattern is inside the output. */
    boolean contains(String pattern) {
        String str = buffer.toString();
        return str.contains(pattern);
    }

    /* Runs as a separate thread capturing all output in a StringBuffer */
    public void run() {
        try {
            byte b[] = new byte[100];
            for (;;) {
                int n = in.read(b);
                String str;
                if (n < 0) {
                    break;
                }
                str = new String(b, 0, n);
                buffer.append(str);
                System.out.print(str);
            }
        } catch (IOException ioe) { /* skip */ }
    }
}

/*
 * Main JVMTI Demo Run class.
 */
public class DemoRun {

    private String        demo_name;
    private String        demo_options;
    private MyInputStream output;
    private MyInputStream error;

    /* Create a Demo run process */
    public DemoRun(String name, String options)
    {
        demo_name    = name;
        demo_options = options;
    }

    /*
     * Execute a process with an -agentpath or -agentlib command option
     */
    public void runit(String class_name)
    {
        runit(class_name, null);
    }

    /*
     * Execute a process with an -agentpath or -agentlib command option
     *    plus any set of other java options.
     */
    public void runit(String class_name, String vm_options[])
    {
        String jre_home  = System.getProperty("java.home");
        String sdk_home  = (jre_home.endsWith("jre") ?
                            (jre_home + File.separator + "..") :
                            jre_home );
        String cdir      = System.getProperty("test.classes", ".");
        String os_arch   = System.getProperty("os.arch");
        String os_name   = System.getProperty("os.name");
        String libprefix = os_name.contains("Windows")?"":"lib";
        String libsuffix = os_name.contains("Windows")?".dll":".so";
        boolean d64      =    ( os_name.contains("Solaris") ||
                                os_name.contains("SunOS") )
                           && ( os_arch.equals("sparcv9") ||
                                os_arch.equals("amd64"));
        boolean hprof    = demo_name.equals("hprof");
        String isa_dir   = d64?(File.separator+os_arch):"";
        String java      = jre_home
                             + File.separator + "bin" + isa_dir
                             + File.separator + "java";
        /* Array of strings to be passed in for exec:
         *   1. java
         *   2. -Dtest.classes=.
         *   3. -d64                 (optional)
         *   4. -Xcheck:jni          (Just because it finds bugs)
         *   5. -Xverify:all         (Make sure verification is on full blast)
         *   6. -agent
         *       vm_options
         *   7+i. classname
         */
        int nvm_options = 0;
        if ( vm_options != null ) nvm_options = vm_options.length;
        String cmd[]     = new String[1 + (d64?1:0) + 5 + nvm_options];
        String cmdLine;
        int exitStatus;
        int i,j;

        i = 0;
        cmdLine = "";
        cmdLine += (cmd[i++] = java);
        cmdLine += " ";
        cmdLine += (cmd[i++] = "-Dtest.classes=" + cdir);
        if ( d64 ) {
            cmdLine += " ";
            cmdLine += (cmd[i++] = "-d64");
        }
        cmdLine += " ";
        cmdLine += (cmd[i++] = "-Xcheck:jni");
        cmdLine += " ";
        cmdLine += (cmd[i++] = "-Xverify:all");
        if ( hprof ) {
            /* Load hprof with -agentlib since it's part of jre */
            cmdLine += " ";
            cmdLine += (cmd[i++] = "-agentlib:" + demo_name
                     + (demo_options.equals("")?"":("="+demo_options)));
        } else {
            String libname  = sdk_home
                         + File.separator + "demo"
                         + File.separator + "jvmti"
                         + File.separator + demo_name
                         + File.separator + "lib" + isa_dir
                         + File.separator + libprefix + demo_name + libsuffix;
            cmdLine += " ";
            cmdLine += (cmd[i++] = "-agentpath:" + libname
                     + (demo_options.equals("")?"":("="+demo_options)));
        }
        /* Add any special VM options */
        for ( j = 0; j < nvm_options; j++ ) {
            cmdLine += " ";
            cmdLine += (cmd[i++] = vm_options[j]);
        }
        /* Add classname */
        cmdLine += " ";
        cmdLine += (cmd[i++] = class_name);

        /* Begin process */
        Process p;

        System.out.println("Starting: " + cmdLine);
        try {
            p = Runtime.getRuntime().exec(cmd);
        } catch ( IOException e ) {
            throw new RuntimeException("Test failed - exec got IO exception");
        }

        /* Save process output in StringBuffers */
        output = new MyInputStream("Input Stream", p.getInputStream());
        error  = new MyInputStream("Error Stream", p.getErrorStream());

        /* Wait for process to complete, and if exit code is non-zero we fail */
        try {
            exitStatus = p.waitFor();
            if ( exitStatus != 0) {
                System.out.println("Exit code is " + exitStatus);
                error.dump(System.out);
                output.dump(System.out);
                throw new RuntimeException("Test failed - " +
                                    "exit return code non-zero " +
                                    "(exitStatus==" + exitStatus + ")");
            }
        } catch ( InterruptedException e ) {
            throw new RuntimeException("Test failed - process interrupted");
        }
        System.out.println("Completed: " + cmdLine);
    }

    /* Does the pattern appear in the output of this process */
    public boolean output_contains(String pattern)
    {
        return output.contains(pattern) || error.contains(pattern);
    }
}
