/**
 * @test
 * @enablePreview
 * @run build TestScaffold VMConnection TargetListener TargetAdapter
 * @run compile SuspendAfterDeath.java
 * @run main/othervm SuspendAfterDeath
 */
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;

class SuspendAfterDeathTarg {

    // breakpoint here
    static void done() {
    }

    public static void main(String[] args) throws Exception {
        Thread thread = Thread.ofVirtual().name("duke").start(() -> { });
        thread.join();
        done();
    }
}

public class SuspendAfterDeath extends TestScaffold {
    private volatile ThreadReference vthread;

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

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

    @Override
    public void threadDied(ThreadDeathEvent event) {
        ThreadReference thread = event.thread();
        if (thread.isVirtual()) {
            vthread = thread;
        }
    }

    @Override
    public void breakpointReached(BreakpointEvent event) {
        System.out.println("breakpoint, vthread=" + vthread);
        vthread.suspend();
    }

    @Override
    public void connect(String args[]) {
        // insert --enable-preview
        int len = args.length;
        String[] newargs = new String[len+1];
        newargs[0] = "--enable-preview";
        System.arraycopy(args, 0, newargs, 1, len);
        super.connect(newargs);
    }

    @Override
    protected void runTests() throws Exception {
        BreakpointEvent bpe = startToMain("SuspendAfterDeathTarg");
        EventRequestManager erm = vm().eventRequestManager();

        // listener for ThreadDeathEvent captures reference to virtual thread
        ThreadDeathRequest request1 = erm.createThreadDeathRequest();
        request1.enable();

        // listener for BreakpointEvent attempts to suspend virtual thread
        ReferenceType targetClass = bpe.location().declaringType();
        Location loc = findMethod(targetClass, "done", "()V").location();
        BreakpointRequest request2 = erm.createBreakpointRequest(loc);
        request2.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
        request2.enable();

        listenUntilVMDisconnect();
        if (testFailed) {
            throw new Exception("SuspendAfterDeath failed");
        }
    }
}
