/*
 * Copyright 2001-2002 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 4451941 4527072
 *  @summary Test argument types for invoke
 *
 *  @author Robert Field
 *
 *  @library ..
 *  @run build  TestScaffold VMConnection TargetListener TargetAdapter
 *  @run compile -g InvokeTest.java
 *  @run main InvokeTest
 */
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;

import java.util.*;

    /********** target program **********/

class InvokeTarg {
    static InvokeTarg myself = null;

    boolean[] aBooleanArray = new boolean[] {true, true};
    byte[] aByteArray = new byte[] {4, 2};
    char[] aCharArray = new char[] {'k', 'p'};
    short[] aShortArray = new short[] {55,12, 12};
    int[] aIntArray = new int[] {6, 3, 1};
    long[] aLongArray = new long[] {3423423};
    float[] aFloatArray = new float[] {(float)2.1};
    double[] aDoubleArray = new double[] {3.141595358979};

    boolean[][] aBoolean2DArray = new boolean[][]
                                   {{true, false}, {false, true}};
    byte[][] aByte2DArray = new byte[][] {{22,66}, {8,9}};
    char[][] aChar2DArray = new char[][] {{22,66}, {8,9}};
    short[][] aShort2DArray = new short[][] {{22,66}, {8,9}};
    int[][] aInt2DArray = new int[][] {{22,66}, {8,9}};
    long[][] aLong2DArray = new long[][] {{22,66}, {8,9}};
    float[][] aFloat2DArray = new float[][] {{22,66}, {8,9}};
    double[][] aDouble2DArray = new double[][] {{22,66}, {8,9}};

    String[] aStringArray = new String[] {"testing"};
    String[][] aString2DArray = new String[][]
                                     {{"hi", "there"}, {"oh"}};
    Date aDate = new Date();
    Date[] aDateArray = new Date[] {};
    Date[][] aDate2DArray = new Date[][] {{}};

    String aString = "jjxx";
    long longCheck = 0;
    boolean booleanCheck = false;
    boolean voidCheck = false;
    Object objectCheck = null;

    public static void main(String[] args){
        System.out.println("Howdy!");
        (new InvokeTarg()).sayHi();
    }

    void sayHi() {
    }

    void checkIn() {
    }

    boolean invokeVoid() {
        voidCheck = true;
        checkIn();
        return true;
    }

    boolean invokeBoolean(boolean val) {
        booleanCheck = val;
        checkIn();
        return val;
    }

    byte invokeByte(byte val) {
        longCheck = val;
        checkIn();
        return val;
    }

    char invokeChar(char val) {
        longCheck = val;
        checkIn();
        return val;
    }

    short invokeShort(short val) {
        longCheck = val;
        checkIn();
        return val;
    }

    int invokeInt(int val) {
        longCheck = val;
        checkIn();
        return val;
    }

    long invokeLong(long val) {
        longCheck = val;
        checkIn();
        return val;
    }

    float invokeFloat(float val) {
        longCheck = (long)val;
        checkIn();
        return val;
    }

    double invokeDouble(double val) {
        longCheck = (long)val;
        checkIn();
        return val;
    }

    boolean[] invokeBooleanArray(boolean[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    byte[] invokeByteArray(byte[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    char[] invokeCharArray(char[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    short[] invokeShortArray(short[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    int[] invokeIntArray(int[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    long[] invokeLongArray(long[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    float[] invokeFloatArray(float[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    double[] invokeDoubleArray(double[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    boolean[][] invokeBoolean2DArray(boolean[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    byte[][] invokeByte2DArray(byte[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    char[][] invokeChar2DArray(char[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    short[][] invokeShort2DArray(short[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    int[][] invokeInt2DArray(int[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    long[][] invokeLong2DArray(long[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    float[][] invokeFloat2DArray(float[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    double[][] invokeDouble2DArray(double[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    String invokeString(String val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    String[] invokeStringArray(String[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    String[][] invokeString2DArray(String[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    Date invokeDate(Date val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    Date[] invokeDateArray(Date[] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    Date[][] invokeDate2DArray(Date[][] val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    String invokeCombo(int[][] arr, String val) {
        objectCheck = val;
        checkIn();
        return val;
    }

    int[][] invokeCombo2(int[][] val, String str) {
        objectCheck = val;
        checkIn();
        return val;
    }
}

    /********** test program **********/

public class InvokeTest extends TestScaffold {
    ReferenceType targetClass;
    ThreadReference mainThread;
    ObjectReference thisObject;
    Field longCheckField;
    Field booleanCheckField;
    Field voidCheckField;
    Field objectCheckField;
    Value longValue;
    Value booleanValue;
    Value objectValue;
    Value voidValue;

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

    public static void main(String[] args)      throws Exception {
        new InvokeTest(args).startTests();
    }

    /********** event handlers **********/

    // not use now
    public void breakpointReached(BreakpointEvent event) {
        println("Got BreakpointEvent");
        longValue = thisObject.getValue(longCheckField);
        booleanValue = thisObject.getValue(booleanCheckField);
        objectValue = thisObject.getValue(objectCheckField);
        voidValue = thisObject.getValue(voidCheckField);
    }

    /********** test assist **********/

    void invoke(Method method, List args, Value value) {
        Value returnValue = null;

        try {
            returnValue = thisObject.invokeMethod(mainThread,
                                                    method, args, 0);
        } catch ( Exception ee) {
            println("Got Exception: " + ee);
            ee.printStackTrace();
        }
        println("        return val = " + returnValue);
        // It has to be the same value as what we passed in!
        if (returnValue.equals(value)) {
            println("         " + method.name() + " return value matches: "
                    + value);
        } else {
            if (value != null) {
                failure("FAIL: " + method.name() + " returned: " + returnValue +
                        " expected: " + value );
            } else {
                println("         " + method.name() + " return value : " + returnValue);
            }

        }
        Value checkValue = (value instanceof PrimitiveValue)?
                              ((value instanceof BooleanValue)?
                                        booleanValue : longValue) :
                              objectValue;
    }


    void invoke(String methodName, String methodSig,
                List args, Value value)
        throws Exception {
        Method method = findMethod(targetClass, methodName, methodSig);
        if ( method == null) {
            failure("FAILED: Can't find method: " + methodName  + " for class = " + targetClass);
            return;
        }
        invoke(method, args, value);
    }

    void invoke(String methodName, String methodSig, Value value)
                                           throws Exception {
        List args = new ArrayList(1);
        args.add(value);
        invoke(methodName, methodSig, args, value);
    }


    void invoke(String methodName, String methodSig, String fieldName)
                                           throws Exception {
        invoke(methodName, methodSig, fieldValue(fieldName));
    }

    private Method toStringMethod;
    Method gettoStringMethod() {
        if ( toStringMethod != null) {
            return toStringMethod;
        }

        // We have to find it.  First find java.lang.Object
        List myClasses = vm().allClasses();
        Iterator iter = myClasses.iterator();
        ReferenceType objectMirror = null;
        while (iter.hasNext()) {
            ReferenceType xx = (ReferenceType)iter.next();
            if (xx.name().equals("java.lang.Object")) {
                objectMirror = xx;
                break;
            }
        }

        if (objectMirror == null) {
            return null;
        }

        // Then find toSting
        List meths = objectMirror.methods();
        iter = meths.iterator();
        while (iter.hasNext()) {
            toStringMethod = (Method)iter.next();
            if (toStringMethod.name().equals("toString")) {
                return toStringMethod;
           }
       }
       toStringMethod = null;
       return null;
    }

    // This calls toString on a field
    protected void callToString(String fieldName) throws Exception {
        // Sorry for this kludgy use of global vars.
        ObjectReference saveObject = thisObject;
        Method toStringMethod = gettoStringMethod();

        Field theField = targetClass.fieldByName(fieldName);
        thisObject = (ObjectReference)thisObject.getValue( theField);
        invoke(toStringMethod, new ArrayList(0), null);
        thisObject = saveObject;
    }

    Value fieldValue(String fieldName) {
        Field field = targetClass.fieldByName(fieldName);
        return thisObject.getValue(field);
    }


    /********** test core **********/

    protected void runTests() throws Exception {
        /*
         * Get to the top of sayHi()
         * to determine targetClass and mainThread
         */
        BreakpointEvent bpe = startTo("InvokeTarg", "sayHi", "()V");
        targetClass = bpe.location().declaringType();

        mainThread = bpe.thread();

        StackFrame frame = mainThread.frame(0);
        thisObject = frame.thisObject();
        longCheckField = targetClass.fieldByName("longCheck");
        booleanCheckField = targetClass.fieldByName("booleanCheck");
        objectCheckField = targetClass.fieldByName("objectCheck");
        voidCheckField = targetClass.fieldByName("voidCheck");
        callToString("aBooleanArray");

        invoke("invokeVoid",    "()Z",  new ArrayList(0), vm().mirrorOf(true));

        invoke("invokeBoolean", "(Z)Z", vm().mirrorOf(true));
        invoke("invokeByte",    "(B)B", vm().mirrorOf((byte)14));
        invoke("invokeChar",    "(C)C", vm().mirrorOf('h'));
        invoke("invokeShort",   "(S)S", vm().mirrorOf((short)54));
        invoke("invokeInt",     "(I)I", vm().mirrorOf((int)414));
        invoke("invokeLong",    "(J)J", vm().mirrorOf((long)140000));
        invoke("invokeFloat",   "(F)F", vm().mirrorOf((float)315));
        invoke("invokeDouble",  "(D)D", vm().mirrorOf((double)181818));

        invoke("invokeBooleanArray",    "([Z)[Z", "aBooleanArray");
        invoke("invokeByteArray",    "([B)[B", "aByteArray");
        invoke("invokeCharArray",    "([C)[C", "aCharArray");
        invoke("invokeShortArray",   "([S)[S", "aShortArray");
        invoke("invokeIntArray",     "([I)[I", "aIntArray");
        invoke("invokeLongArray",    "([J)[J", "aLongArray");
        invoke("invokeFloatArray",   "([F)[F", "aFloatArray");
        invoke("invokeDoubleArray",  "([D)[D", "aDoubleArray");

        invoke("invokeBoolean2DArray",    "([[Z)[[Z", "aBoolean2DArray");
        invoke("invokeByte2DArray",    "([[B)[[B", "aByte2DArray");
        invoke("invokeChar2DArray",    "([[C)[[C", "aChar2DArray");
        invoke("invokeShort2DArray",   "([[S)[[S", "aShort2DArray");
        invoke("invokeInt2DArray",     "([[I)[[I", "aInt2DArray");
        invoke("invokeLong2DArray",    "([[J)[[J", "aLong2DArray");
        invoke("invokeFloat2DArray",   "([[F)[[F", "aFloat2DArray");
        invoke("invokeDouble2DArray",  "([[D)[[D", "aDouble2DArray");

        invoke("invokeString",    "(Ljava/lang/String;)Ljava/lang/String;",
                                  vm().mirrorOf("Howdy"));
        invoke("invokeStringArray",    "([Ljava/lang/String;)[Ljava/lang/String;",
                                  "aStringArray");
        invoke("invokeString2DArray",    "([[Ljava/lang/String;)[[Ljava/lang/String;",
                                  "aString2DArray");

        invoke("invokeDate",    "(Ljava/util/Date;)Ljava/util/Date;",
                                  "aDate");
        invoke("invokeDateArray",  "([Ljava/util/Date;)[Ljava/util/Date;",
                                  "aDateArray");
        invoke("invokeDate2DArray", "([[Ljava/util/Date;)[[Ljava/util/Date;",
                                  "aDate2DArray");

        Value i2 = fieldValue("aInt2DArray");
        Value str = vm().mirrorOf("Later");
        List args = new ArrayList(2);
        args.add(i2);
        args.add(str);
        invoke("invokeCombo",
               "([[ILjava/lang/String;)Ljava/lang/String;",
               args, str);
        invoke("invokeCombo2",
               "([[ILjava/lang/String;)[[I",
               args, i2);
        /*
         * resume the target listening for events
         */
        listenUntilVMDisconnect();

        /*
         * deal with results of test
         * if anything has called failure("foo") testFailed will be true
         */
        if (!testFailed) {
            println("InvokeTest: passed");
        } else {
            throw new Exception("InvokeTest: failed");
        }
    }
}
