/*
 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. 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 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 6426034
 *  @summary Instance filter doesn't filter event if it occurs in native method
 *
 *  @author Keith McGuigan
 *
 *  @modules jdk.jdi
 *  @run build JDIScaffold VMConnection
 *  @compile -XDignore.symbol.file NativeInstanceFilterTarg.java
 *  @run driver NativeInstanceFilter
 */

/*
 *  This test tests instance filters for events generated from a native method
 */

import java.util.*;
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;

public class NativeInstanceFilter extends JDIScaffold {

    static int unfilteredEvents = 0;

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

    public NativeInstanceFilter() {
        super();
    }

    static EventRequestManager requestManager = null;
    static MethodExitRequest request = null;
    static ThreadReference mainThread = null;

    private void listen() {
        TargetAdapter adapter = new TargetAdapter() {
            EventSet set = null;
            ObjectReference instance = null;

            public boolean eventSetReceived(EventSet set) {
                this.set = set;
                return false;
            }

            public boolean methodExited(MethodExitEvent event) {
                String name = event.method().name();
                if (instance == null && name.equals("latch")) {
                    // Grab the instance (return value) and set up as filter
                    System.out.println("Setting up instance filter");
                    instance = (ObjectReference)event.returnValue();
                    requestManager.deleteEventRequest(request);
                    request = requestManager.createMethodExitRequest();
                    request.addInstanceFilter(instance);
                    request.addThreadFilter(mainThread);
                    request.enable();
                } else if (instance != null && name.equals("intern")) {
                    // If not for the filter, this will be called twice
                    System.out.println("method exit event (String.intern())");
                    ++unfilteredEvents;
                }
                set.resume();
                return false;
            }
        };
        addListener(adapter);
    }


    protected void runTests() throws Exception {
        String[] args = new String[2];
        args[0] = "-connect";
        args[1] = "com.sun.jdi.CommandLineLaunch:main=NativeInstanceFilterTarg";

        connect(args);
        waitForVMStart();

        // VM has started, but hasn't started running the test program yet.
        requestManager = vm().eventRequestManager();
        ClassPrepareEvent e = resumeToPrepareOf("NativeInstanceFilterTarg");
        ReferenceType referenceType = e.referenceType();
        mainThread = e.thread();

        request = requestManager.createMethodExitRequest();
        request.addThreadFilter(mainThread);
        request.enable();

        listen();

        vm().resume();

        waitForVMDeath();

        if (unfilteredEvents != 1) {
            throw new Exception(
                "Failed: Event from native frame not filtered out.");
        }
        System.out.println("Passed: Event filtered out.");
    }
}
