/*
 * Copyright 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
 *  @bug 6431735
 *  @summary Unexpected ClassCastException in ThreadReference.forceEarlyReturn
 *  @author Jim Holmlund
 *
 *  @run build TestScaffold VMConnection TargetListener TargetAdapter
 *  @run compile -g EarlyReturnNegativeTest.java
 *  @run main EarlyReturnNegativeTest
 */
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import java.util.*;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.reflect.Array;

/*
 * This test has a debuggee which calls an instance method
 * for each kind of JDI value return type.
 *
 * The debugger sets breakpoints in all methods.  When a breakpoint
 * is hit the debugger requests an early return and supplies a new
 * return value. The new value is not compatible with the method's
 * return type so an InvalidTypeException should be thrown.
 *
 * Each value is stored in a static var in the debuggee.  The debugger
 * gets the values from these static vars to pass back to the
 * debuggee in forceEarlyReturn.
 *
 * This test was created out of EarlyReturnTest.java.  Not all of the
 * debuggee methods are actually used, just the ones needed to test
 * for correct operation.  I left the others in just in case they come
 * in handy in the future.
 */

class EarlyReturnNegativeTarg {
    /*
     * These are the values that will be used by methods
     * returning normally.
     */
    static URL[] urls = new URL[1];
    public static byte      byteValue = 89;
    public static char      charValue = 'x';
    public static double    doubleValue = 2.2;
    public static float     floatValue = 3.3f;
    public static int       intValue = 1;
    public static long      longValue = Long.MAX_VALUE;
    public static short     shortValue = 8;
    public static boolean   booleanValue = false;

    public static Class       classValue = Object.class;
    public static ClassLoader classLoaderValue;
    {
        try {
            urls[0] = new URL("hi there");
        } catch (java.net.MalformedURLException ee) {
        }
        classLoaderValue = new URLClassLoader(urls);
    }

    public static Thread      threadValue = Thread.currentThread();
    public static ThreadGroup threadGroupValue = threadValue.getThreadGroup();
    public static String      stringValue = "abc";
    public static int[]       intArrayValue = new int[] {1, 2, 3};
    public static Object[]    objectArrayValue = new Object[] {"a", "b", "c"};

    public static EarlyReturnNegativeTarg  objectValue =
        new EarlyReturnNegativeTarg();
    public String ivar = stringValue;


    // Used to show which set of tests follows
    public static String s_show(String p1) { return p1;}

    // These are the instance methods
    public byte i_bytef()            { return byteValue; }
    public char i_charf()            { return charValue; }
    public double i_doublef()        { return doubleValue; }
    public float i_floatf()          { return floatValue; }
    public int i_intf()              { return intValue; }
    public long i_longf()            { return longValue; }
    public short i_shortf()          { return shortValue; }
    public boolean i_booleanf()      { return booleanValue; }
    public String i_stringf()        { return stringValue; }
    public Class i_classf()          { return classValue; }
    public ClassLoader i_classLoaderf()
                                     { return classLoaderValue; }
    public Thread i_threadf()        { return threadValue; }
    public ThreadGroup i_threadGroupf()
                                     { return threadGroupValue; }
    public int[] i_intArrayf()       { return intArrayValue; }
    public Object[] i_objectArrayf() { return objectArrayValue; }
    public Object i_nullObjectf()    { return null; }
    public Object i_objectf()        { return objectValue; }
    public void i_voidf()            {}

    static void doit(EarlyReturnNegativeTarg xx) throws Exception {
        System.err.print("debugee in doit ");

        s_show("==========  Testing instance methods ================");
        xx.i_bytef();
        xx.i_charf();
        xx.i_doublef();
        xx.i_floatf();
        xx.i_intf();
        xx.i_longf();
        xx.i_shortf();
        xx.i_booleanf();
        xx.i_stringf();
        xx.i_intArrayf();
        xx.i_objectArrayf();
        xx.i_classf();
        xx.i_classLoaderf();
        xx.i_threadf();
        xx.i_threadGroupf();
        xx.i_nullObjectf();
        xx.i_objectf();
        xx.i_voidf();

    }

    public static void main(String[] args) throws Exception {
        /*
         * The debugger will stop at the start of main,
         * set breakpoints and then do a resume.
         */
        System.err.println("debugee in main");

        EarlyReturnNegativeTarg xx =
            new EarlyReturnNegativeTarg();

        doit(xx);
    }
}



public class EarlyReturnNegativeTest extends TestScaffold {

    static VirtualMachineManager vmm ;
    ClassType targetClass;
    Field theValueField;

    ByteValue byteVV;
    CharValue charVV;
    DoubleValue doubleVV;
    FloatValue floatVV;
    IntegerValue integerVV;
    LongValue longVV;
    ShortValue shortVV;
    BooleanValue booleanVV;
    ObjectReference objectVV;
    ArrayReference intArrayVV;
    ArrayReference objectArrayVV;
    VoidValue voidVV;

    EarlyReturnNegativeTest(String args[]) {
        super(args);
    }

    public static void main(String[] args)      throws Exception {
        EarlyReturnNegativeTest meee = new EarlyReturnNegativeTest(args);
        vmm = Bootstrap.virtualMachineManager();
        meee.startTests();
    }

    public BreakpointRequest setBreakpoint(String clsName,
                                           String methodName,
                                           String methodSignature) {
        ReferenceType rt = findReferenceType(clsName);
        if (rt == null) {
            rt = resumeToPrepareOf(clsName).referenceType();
        }

        Method method = findMethod(rt, methodName, methodSignature);
        if (method == null) {
            throw new IllegalArgumentException("Bad method name/signature");
        }
        BreakpointRequest bpr = eventRequestManager().createBreakpointRequest(method.location());
        bpr.setSuspendPolicy(EventRequest.SUSPEND_ALL);
        bpr.enable();
        return bpr;
    }

    void doEarly(ThreadReference tr, String methodName, Value val) {
        try {
            tr.forceEarlyReturn(val);
        } catch (InvalidTypeException ex) {
            System.out.println("Ok: " + methodName);
            return;
        } catch (Exception ex) {
            failure("failure: " + ex.toString());
            ex.printStackTrace();
            return;
        }
        failure("Expected InvalidTypeException for " + methodName + ", " + val + " but didn't get it.");
    }

    public void breakpointReached(BreakpointEvent event) {
        String origMethodName = event.location().method().name();
        String methodName = origMethodName.substring(2);
        ThreadReference tr = event.thread();

        if (vmm.majorInterfaceVersion() >= 1 &&
            vmm.minorInterfaceVersion() >= 6 &&
            vm().canForceEarlyReturn()) {

            /* There are some incompatible classes of values.  In the following,
             * we test each combination.
             */
            if ("shortf".equals(methodName)){
                doEarly(tr, origMethodName, booleanVV);
                doEarly(tr, origMethodName, objectVV);
                doEarly(tr, origMethodName, voidVV);
                doEarly(tr, origMethodName, intArrayVV);
                doEarly(tr, origMethodName, objectArrayVV);

            } else if ("booleanf".equals(methodName)) {
                doEarly(tr, origMethodName, shortVV);
                doEarly(tr, origMethodName, objectVV);
                doEarly(tr, origMethodName, voidVV);
                doEarly(tr, origMethodName, intArrayVV);
                doEarly(tr, origMethodName, objectArrayVV);

            } else if ("intArrayf".equals(methodName)) {
                doEarly(tr, origMethodName, booleanVV);
                doEarly(tr, origMethodName, shortVV);
                doEarly(tr, origMethodName, voidVV);
                doEarly(tr, origMethodName, objectVV);
                doEarly(tr, origMethodName, objectArrayVV);

            } else if ("objectArrayf".equals(methodName)) {
                doEarly(tr, origMethodName, booleanVV);
                doEarly(tr, origMethodName, shortVV);
                doEarly(tr, origMethodName, voidVV);
                doEarly(tr, origMethodName, objectVV);
                doEarly(tr, origMethodName, intArrayVV);

            } else if ("objectf".equals(methodName)) {
                doEarly(tr, origMethodName, booleanVV);
                doEarly(tr, origMethodName, shortVV);
                doEarly(tr, origMethodName, voidVV);

             } else if ("voidf".equals(methodName)) {
                doEarly(tr, origMethodName, booleanVV);
                doEarly(tr, origMethodName, shortVV);
                doEarly(tr, origMethodName, objectVV);
                doEarly(tr, origMethodName, intArrayVV);
                doEarly(tr, origMethodName, objectArrayVV);

            } else {
                // just ignore others
                System.out.println("Ignoring: " + methodName);
                return;
            }
        } else {
            System.out.println("Cannot force early return for method: " + origMethodName);
        }
    }

    protected void runTests() throws Exception {
        /*
         * Get to the top of main()
         * to determine targetClass and mainThread
         */

        BreakpointEvent bpe = startToMain("EarlyReturnNegativeTarg");
        targetClass = (ClassType)bpe.location().declaringType();
        mainThread = bpe.thread();

        /*
         * We set and enable breakpoints on all of the interesting
         * methods called by doit().  In the breakpointReached()
         * handler we force an early return with a different return
         * value.
         *
         */

        setBreakpoint("EarlyReturnNegativeTarg", "i_bytef", "()B");
        setBreakpoint("EarlyReturnNegativeTarg", "i_charf", "()C");
        setBreakpoint("EarlyReturnNegativeTarg", "i_doublef", "()D");
        setBreakpoint("EarlyReturnNegativeTarg", "i_floatf", "()F");
        setBreakpoint("EarlyReturnNegativeTarg", "i_intf", "()I");
        setBreakpoint("EarlyReturnNegativeTarg", "i_longf", "()J");
        setBreakpoint("EarlyReturnNegativeTarg", "i_shortf", "()S");
        setBreakpoint("EarlyReturnNegativeTarg", "i_booleanf", "()Z");
        setBreakpoint("EarlyReturnNegativeTarg", "i_stringf", "()Ljava/lang/String;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_intArrayf", "()[I");
        setBreakpoint("EarlyReturnNegativeTarg", "i_objectArrayf", "()[Ljava/lang/Object;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_classf", "()Ljava/lang/Class;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_classLoaderf", "()Ljava/lang/ClassLoader;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_threadf", "()Ljava/lang/Thread;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_threadGroupf", "()Ljava/lang/ThreadGroup;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_nullObjectf", "()Ljava/lang/Object;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_objectf", "()Ljava/lang/Object;");
        setBreakpoint("EarlyReturnNegativeTarg", "i_voidf", "()V");

        /* Create Value objects to be passed in forceEarlyReturn calls */
        Field theValueField = targetClass.fieldByName("byteValue");
        byteVV = (ByteValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("charValue");
        charVV = (CharValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("doubleValue");
        doubleVV = (DoubleValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("floatValue");
        floatVV = (FloatValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("intValue");
        integerVV = (IntegerValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("longValue");
        longVV = (LongValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("shortValue");
        shortVV = (ShortValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("booleanValue");
        booleanVV = (BooleanValue)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("objectValue");
        objectVV = (ObjectReference)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("intArrayValue");
        intArrayVV = (ArrayReference)targetClass.getValue(theValueField);

        theValueField = targetClass.fieldByName("objectArrayValue");
        objectArrayVV = (ArrayReference)targetClass.getValue(theValueField);

        voidVV = vm().mirrorOfVoid();

        /* Here we go.  This adds 'this' as a listener so
         * that our handlers above will be called.
         */
        listenUntilVMDisconnect();

        if (!testFailed) {
            System.out.println();
            System.out.println("EarlyReturnNegativeTest: passed");
        } else {
            System.out.println();
            System.out.println("EarlyReturnNegativeTest: failed");
            throw new Exception("EarlyReturnNegativeTest: failed");
        }
    }
}
