/*
 * Copyright (c) 2019, 2023, 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
 * @summary Test virtual threads using java.util.concurrent locks
 * @library /test/lib
 * @run junit Locking
 */

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

import jdk.test.lib.thread.VThreadRunner;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class Locking {

    /**
     * Test lock/unlock.
     */
    @Test
    void testReentrantLock1() throws Exception {
        VThreadRunner.run(() -> {
            ReentrantLock lock = new ReentrantLock();
            assertFalse(lock.isHeldByCurrentThread());
            lock.lock();
            assertTrue(lock.isHeldByCurrentThread());
            lock.unlock();
            assertFalse(lock.isHeldByCurrentThread());
        });
    }

    /**
     * Test tryLock/unlock.
     */
    @Test
    void testReentrantLock2() throws Exception {
        VThreadRunner.run(() -> {
            ReentrantLock lock = new ReentrantLock();
            assertFalse(lock.isHeldByCurrentThread());
            boolean acquired = lock.tryLock();
            assertTrue(acquired);
            assertTrue(lock.isHeldByCurrentThread());
            lock.unlock();
            assertFalse(lock.isHeldByCurrentThread());
        });
    }

    /**
     * Test lock/lock/unlock/unlock.
     */
    @Test
    void testReentrantLock3() throws Exception {
        VThreadRunner.run(() -> {
            ReentrantLock lock = new ReentrantLock();
            assertFalse(lock.isHeldByCurrentThread());
            assertTrue(lock.getHoldCount() == 0);
            lock.lock();
            assertTrue(lock.isHeldByCurrentThread());
            assertTrue(lock.getHoldCount() == 1);
            lock.lock();
            assertTrue(lock.isHeldByCurrentThread());
            assertTrue(lock.getHoldCount() == 2);
            lock.unlock();
            assertTrue(lock.isHeldByCurrentThread());
            assertTrue(lock.getHoldCount() == 1);
            lock.unlock();
            assertFalse(lock.isHeldByCurrentThread());
            assertTrue(lock.getHoldCount() == 0);
        });
    }

    /**
     * Test locked by platform thread, virtual thread tries to lock.
     */
    @Test
    void testReentrantLock4() throws Exception {
        ReentrantLock lock = new ReentrantLock();
        var holdsLock = new AtomicBoolean();

        Thread thread;

        // thread acquires lock
        lock.lock();
        try {
            thread = Thread.ofVirtual().start(() -> {
                lock.lock();  // should block
                holdsLock.set(true);
                LockSupport.park();
                lock.unlock();
                holdsLock.set(false);
            });
            // give time for virtual thread to block
            Thread.sleep(500);
            assertFalse(holdsLock.get());
        } finally {
            lock.unlock();
        }

        // virtual thread should acquire lock, park, unpark, and then release lock
        while (!holdsLock.get()) {
            Thread.sleep(20);
        }
        LockSupport.unpark(thread);
        while (holdsLock.get()) {
            Thread.sleep(20);
        }
        thread.join();
    }

    /**
     * Test locked by virtual thread, platform thread tries to lock.
     */
    @Test
    void testReentrantLock5() throws Exception {
        ReentrantLock lock = new ReentrantLock();
        var thread = Thread.ofVirtual().start(() -> {
            lock.lock();
            try {
                LockSupport.park();
            } finally {
                lock.unlock();
            }
        });

        // wat for virtual thread to acquire lock
        while (!lock.isLocked()) {
            Thread.sleep(20);
        }

        // thread cannot acquire lock
        try {
            assertFalse(lock.tryLock());
        } finally {
            // virtual thread should unlock
            LockSupport.unpark(thread);

            // thread should be able to acquire lock
            lock.lock();
            lock.unlock();
            thread.join();
        }
    }

    /**
     * Test locked by virtual thread, another virtual thread tries to lock.
     */
    @Test
    void testReentrantLock6() throws Exception {
        ReentrantLock lock = new ReentrantLock();
        var thread1 = Thread.ofVirtual().start(() -> {
            lock.lock();
            try {
                LockSupport.park();
            } finally {
                lock.unlock();
            }
        });

        // wat for virtual thread to acquire lock
        while (!lock.isLocked()) {
            Thread.sleep(10);
        }

        var holdsLock  = new AtomicBoolean();
        var thread2 = Thread.ofVirtual().start(() -> {
            lock.lock();
            holdsLock.set(true);
            LockSupport.park();
            lock.unlock();
            holdsLock.set(false);
        });

        // virtual thread2 should block
        Thread.sleep(1000);
        assertFalse(holdsLock.get());

        // unpark virtual thread1
        LockSupport.unpark(thread1);

        // virtual thread2 should acquire lock
        while (!holdsLock.get()) {
            Thread.sleep(20);
        }
        // unpark virtual thread and it should release lock
        LockSupport.unpark(thread2);
        while (holdsLock.get()) {
            Thread.sleep(20);
        }

        thread1.join();
        thread2.join();
    }
}
