/*
 * Copyright (c) 2016 Red Hat Inc.
 *
 * 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 8153711
 *  @summary JDWP: Memory Leak (global references not deleted after invokeMethod).
 *
 *  @author Severin Gehwolf <sgehwolf@redhat.com>
 *
 *  @library ..
 *  @run build TestScaffold VMConnection TargetListener TargetAdapter
 *  @run compile -g OomDebugTest.java
 *  @run shell OomDebugTestSetup.sh
 *  @run main OomDebugTest OomDebugTestTarget test1
 *  @run main OomDebugTest OomDebugTestTarget test2
 *  @run main OomDebugTest OomDebugTestTarget test3
 *  @run main OomDebugTest OomDebugTestTarget test4
 *  @run main OomDebugTest OomDebugTestTarget test5
 */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import com.sun.jdi.ArrayReference;
import com.sun.jdi.ArrayType;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.InvocationException;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.StackFrame;
import com.sun.jdi.VMOutOfMemoryException;
import com.sun.jdi.Value;
import com.sun.jdi.event.BreakpointEvent;
import com.sun.jdi.event.ExceptionEvent;

/***************** Target program **********************/

class OomDebugTestTarget {

    OomDebugTestTarget() {
        System.out.println("DEBUG: invoked constructor");
    }
    static class FooCls {
        @SuppressWarnings("unused")
        private byte[] bytes = new byte[3000000];
    };

    FooCls fooCls = new FooCls();
    byte[] byteArray = new byte[0];

    void testMethod(FooCls foo) {
        System.out.println("DEBUG: invoked 'void testMethod(FooCls)', foo == " + foo);
    }

    void testPrimitive(byte[] foo) {
        System.out.println("DEBUG: invoked 'void testPrimitive(byte[])', foo == " + foo);
    }

    byte[] testPrimitiveArrRetval() {
        System.out.println("DEBUG: invoked 'byte[] testPrimitiveArrRetval()'");
        return new byte[3000000];
    }

    FooCls testFooClsRetval() {
        System.out.println("DEBUG: invoked 'FooCls testFooClsRetval()'");
        return new FooCls();
    }

    public void entry() {}

    public static void main(String[] args){
        System.out.println("DEBUG: OomDebugTestTarget.main");
        new OomDebugTestTarget().entry();
    }
}

/***************** Test program ************************/

public class OomDebugTest extends TestScaffold {

    private static final String[] ALL_TESTS = new String[] {
            "test1", "test2", "test3", "test4", "test5"
    };
    private static final Set<String> ALL_TESTS_SET = new HashSet<String>();
    static {
        ALL_TESTS_SET.addAll(Arrays.asList(ALL_TESTS));
    }
    private static final String TEST_CLASSES = System.getProperty("test.classes", ".");
    private static final File RESULT_FILE = new File(TEST_CLASSES, "results.properties");
    private static final String LAST_TEST = ALL_TESTS[ALL_TESTS.length - 1];
    private ReferenceType targetClass;
    private ObjectReference thisObject;
    private int failedTests;
    private final String testMethod;

    public OomDebugTest(String[] args) {
        super(args);
        if (args.length != 2) {
            throw new RuntimeException("Test failed unexpectedly.");
        }
        this.testMethod = args[1];
    }

    @Override
    protected void runTests() throws Exception {
        try {
            addListener(new TargetAdapter() {

                @Override
                public void exceptionThrown(ExceptionEvent event) {
                    String name = event.exception().referenceType().name();
                    System.err.println("DEBUG: Exception thrown in debuggee was: " + name);
                }
            });
            /*
             * Get to the top of entry()
             * to determine targetClass and mainThread
             */
            BreakpointEvent bpe = startTo("OomDebugTestTarget", "entry", "()V");
            targetClass = bpe.location().declaringType();

            mainThread = bpe.thread();

            StackFrame frame = mainThread.frame(0);
            thisObject = frame.thisObject();
            java.lang.reflect.Method m = findTestMethod();
            m.invoke(this);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            failure();
        } catch (SecurityException e) {
            e.printStackTrace();
            failure();
        }
        /*
         * resume the target, listening for events
         */
        listenUntilVMDisconnect();
    }

    private java.lang.reflect.Method findTestMethod()
            throws NoSuchMethodException, SecurityException {
        return OomDebugTest.class.getDeclaredMethod(testMethod);
    }

    private void failure() {
        failedTests++;
    }

    /*
     * Test case: Object reference as method parameter.
     */
    @SuppressWarnings("unused") // called via reflection
    private void test1() throws Exception {
        System.out.println("DEBUG: ------------> Running test1");
        try {
            Field field = targetClass.fieldByName("fooCls");
            ClassType clsType = (ClassType)field.type();
            Method constructor = getConstructorForClass(clsType);
            for (int i = 0; i < 15; i++) {
                @SuppressWarnings({ "rawtypes", "unchecked" })
                ObjectReference objRef = clsType.newInstance(mainThread,
                                                             constructor,
                                                             new ArrayList(0),
                                                             ObjectReference.INVOKE_NONVIRTUAL);
                if (objRef.isCollected()) {
                    System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP.");
                    continue;
                }
                invoke("testMethod", "(LOomDebugTestTarget$FooCls;)V", objRef);
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    /*
     * Test case: Array reference as method parameter.
     */
    @SuppressWarnings("unused") // called via reflection
    private void test2() throws Exception {
        System.out.println("DEBUG: ------------> Running test2");
        try {
            Field field = targetClass.fieldByName("byteArray");
            ArrayType arrType = (ArrayType)field.type();

            for (int i = 0; i < 15; i++) {
                ArrayReference byteArrayVal = arrType.newInstance(3000000);
                if (byteArrayVal.isCollected()) {
                    System.out.println("DEBUG: Object got GC'ed before we can use it. NO-OP.");
                    continue;
                }
                invoke("testPrimitive", "([B)V", byteArrayVal);
            }
        } catch (VMOutOfMemoryException e) {
            defaultHandleOOMFailure(e);
        }
    }

    /*
     * Test case: Array reference as return value.
     */
    @SuppressWarnings("unused") // called via reflection
    private void test3() throws Exception {
        System.out.println("DEBUG: ------------> Running test3");
        try {
            for (int i = 0; i < 15; i++) {
                invoke("testPrimitiveArrRetval",
                       "()[B",
                       Collections.EMPTY_LIST,
                       vm().mirrorOfVoid());
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    /*
     * Test case: Object reference as return value.
     */
    @SuppressWarnings("unused") // called via reflection
    private void test4() throws Exception {
        System.out.println("DEBUG: ------------> Running test4");
        try {
            for (int i = 0; i < 15; i++) {
                invoke("testFooClsRetval",
                       "()LOomDebugTestTarget$FooCls;",
                       Collections.EMPTY_LIST,
                       vm().mirrorOfVoid());
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    /*
     * Test case: Constructor
     */
    @SuppressWarnings({ "unused", "unchecked", "rawtypes" }) // called via reflection
    private void test5() throws Exception {
        System.out.println("DEBUG: ------------> Running test5");
        try {
            ClassType type = (ClassType)thisObject.type();
            for (int i = 0; i < 15; i++) {
                type.newInstance(mainThread,
                                 findMethod(targetClass, "<init>", "()V"),
                                 new ArrayList(0),
                                 ObjectReference.INVOKE_NONVIRTUAL);
            }
        } catch (InvocationException e) {
            handleFailure(e);
        }
    }

    private Method getConstructorForClass(ClassType clsType) {
        List<Method> methods = clsType.methodsByName("<init>");
        if (methods.size() != 1) {
            throw new RuntimeException("FAIL. Expected only one, the default, constructor");
        }
        return methods.get(0);
    }

    private void handleFailure(InvocationException e) {
        // There is no good way to see the OOME diagnostic message in the target since the
        // TestScaffold might throw an exception while trying to print the stack trace. I.e
        // it might get a a VMDisconnectedException before the stack trace printing finishes.
        System.err.println("FAILURE: InvocationException thrown. Trying to determine cause...");
        defaultHandleOOMFailure(e);
    }

    private void defaultHandleOOMFailure(Exception e) {
        e.printStackTrace();
        failure();
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    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,
                @SuppressWarnings("rawtypes") 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);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    void invoke(Method method, List args, Value value) throws Exception {
        thisObject.invokeMethod(mainThread, method, args, 0);
        System.out.println("DEBUG: Done invoking method via debugger.");
    }

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

    // Determine the pass/fail status on some heuristic and don't fail the
    // test if < 3 of the total number of tests (currently 5) fail. This also
    // has the nice side effect that all tests are first attempted and only
    // all tests ran an overall pass/fail status is determined.
    private static void determineOverallTestStatus(OomDebugTest oomTest)
                                   throws IOException, FileNotFoundException {
        Properties resultProps = new Properties();
        if (!RESULT_FILE.exists()) {
            RESULT_FILE.createNewFile();
        }
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(RESULT_FILE);
            resultProps.load(fin);
            resultProps.put(oomTest.testMethod,
                            Integer.toString(oomTest.failedTests));
        } finally {
            if (fin != null) {
                fin.close();
            }
        }
        System.out.println("DEBUG: Finished running test '"
                           + oomTest.testMethod + "'.");
        if (LAST_TEST.equals(oomTest.testMethod)) {
            System.out.println("DEBUG: Determining overall test status.");
            Set<String> actualTestsRun = new HashSet<String>();
            int totalTests = ALL_TESTS.length;
            int failedTests = 0;
            for (Object key: resultProps.keySet()) {
                actualTestsRun.add((String)key);
                Object propVal = resultProps.get(key);
                int value = Integer.parseInt((String)propVal);
                failedTests += value;
            }
            if (!ALL_TESTS_SET.equals(actualTestsRun)) {
                String errorMsg = "Test failed! Expected to run tests '"
                        + ALL_TESTS_SET + "', but only these were run '"
                        + actualTestsRun + "'";
                throw new RuntimeException(errorMsg);
            }
            if (failedTests >= 3) {
                String errorMsg = "Test failed. Expected < 3 sub-tests to fail "
                                  + "for a pass. Got " + failedTests
                                  + " failed tests out of " + totalTests + ".";
                throw new RuntimeException(errorMsg);
            }
            RESULT_FILE.delete();
            System.out.println("All " + totalTests + " tests passed.");
        } else {
            System.out.println("DEBUG: More tests to run. Coninuing.");
            FileOutputStream fout = null;
            try {
                fout = new FileOutputStream(RESULT_FILE);
                resultProps.store(fout, "Storing results after test "
                                         + oomTest.testMethod);
            } finally {
                if (fout != null) {
                    fout.close();
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        System.setProperty("test.vm.opts", "-Xmx40m"); // Set debuggee VM option
        OomDebugTest oomTest = new OomDebugTest(args);
        try {
            oomTest.startTests();
        } catch (Throwable e) {
            System.out.println("DEBUG: Got exception for test run. " + e);
            e.printStackTrace();
            oomTest.failure();
        }
        determineOverallTestStatus(oomTest);
    }

}
