/*
 * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2015, 2019 IBM Corporation and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     02/24/2015-2.6.0 Rick Curtis
//       - 460740: Fix pessimistic locking with setFirst/Max results on DB2
//     03/13/2015-2.6.0 Will Dazey
//       - 458301: Added tests for force increment on scalar results
//     03/18/2015-2.6.0 Joe Grassel
//       - 462498: Missing isolation level expression in SQL for Derby platform
//     08/14/2015-2.7.0 Tomas Kraus
//       - 453208: Tests disabled for Oracle platform
package org.eclipse.persistence.jpa.test.locking;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.LockModeType;

import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
import org.eclipse.persistence.jpa.JpaEntityManagerFactory;
import org.eclipse.persistence.jpa.test.framework.DDLGen;
import org.eclipse.persistence.jpa.test.framework.Emf;
import org.eclipse.persistence.jpa.test.framework.EmfRunner;
import org.eclipse.persistence.jpa.test.framework.Property;
import org.eclipse.persistence.jpa.test.locking.model.LockingDog;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EmfRunner.class)
public class TestPessimisticLocking {
    @Emf(createTables = DDLGen.DROP_CREATE, classes = { LockingDog.class, }, properties = {
            @Property(name = "eclipselink.cache.shared.default", value = "false") })
    private EntityManagerFactory emf;

    static ExecutorService executor = null;

    /**
     * Get database platform from {@link EntityManagerFactory}.
     * @return Database platform related to provided {@link EntityManager}.
     */
    private Platform getPlatform() {
        return emf.unwrap(JpaEntityManagerFactory.class).getDatabaseSession().getPlatform();
    }

    @BeforeClass
    public static void beforeClass() {
        executor = Executors.newFixedThreadPool(5);
    }

    @AfterClass
    public static void afterClass() {
        executor.shutdownNow();
    }

    List<LockingDog> dogs;

    @Before
    public void before() {
        EntityManager em = emf.createEntityManager();
        dogs = new ArrayList<LockingDog>();
        try {
            em.getTransaction().begin();
            for (int i = 0; i < 10; i++) {
                LockingDog ld = new LockingDog();
                dogs.add(ld);
                em.persist(ld);
            }
            em.getTransaction().commit();
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
        }
    }

    @Test
    public void testPessimisticFind() throws Exception {
        EntityManager em = emf.createEntityManager();
        final EntityManager em2 = emf.createEntityManager();
        final CountDownLatch cdl = new CountDownLatch(2);
        try {
            em.getTransaction().begin();
            em2.getTransaction().begin();

            LockingDog locked = em.find(LockingDog.class, dogs.get(0).getId(), LockModeType.PESSIMISTIC_READ);
            Assert.assertNotNull(locked);
            Callable<LockingDog> blocked = new Callable<LockingDog>() {
                @Override
                public LockingDog call() {
                    cdl.countDown();
                    return em2.find(LockingDog.class, dogs.get(0).getId(), LockModeType.PESSIMISTIC_READ);
                }
            };
            Future<LockingDog> future = executor.submit(blocked);
            cdl.countDown();
            Thread.sleep(3000);
            // Make sure worker is blocked
            Assert.assertFalse(future.isDone());
            // Rolling back of tran should allow worker to complete
            em.getTransaction().rollback();
            Assert.assertEquals(locked.getId(), future.get().getId());

        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            if (em2.getTransaction().isActive()) {
                em2.getTransaction().rollback();
            }
        }
    }

    @Test
    public void testFirstResultPessimisticRead() throws Exception {
        Platform platform = ((EntityManagerFactoryImpl) emf).getServerSession().getDatasourcePlatform();
        // Pessimistic locking with query row limits is not supported on Oracle
        Assume.assumeFalse("Platform " + platform + " is not supported for this test", platform.isOracle());

        EntityManager em = emf.createEntityManager();
        final EntityManager em2 = emf.createEntityManager();
        try {
            em.getTransaction().begin();
            em2.getTransaction().begin();
            em.createNamedQuery("find.lockingdogs", LockingDog.class).setLockMode(LockModeType.PESSIMISTIC_READ).setMaxResults(1).setFirstResult(4).getResultList();
            // This worker should block as he is trying to lock already locked
            // rows
            Future<Boolean> result = executor.submit(new Callable<Boolean>() {
                @Override
                public Boolean call() throws Exception {
                    em2.createNamedQuery("find.lockingdogs", LockingDog.class).setLockMode(LockModeType.PESSIMISTIC_READ).setMaxResults(1).setFirstResult(5).getResultList();
                    return true;
                }
            });
            // Make sure the worker isn't done
            Assert.assertFalse(result.isDone());
            em.getTransaction().rollback();
            // Make sure that the worker obtained the locks and completed
            Assert.assertTrue(result.get());
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
            if (em2.getTransaction().isActive()) {
                em2.getTransaction().rollback();
            }
            em.close();
            em2.close();
        }
    }

    @Test
    public void testMaxResultPessimisticRead() {
        Platform platform = ((EntityManagerFactoryImpl) emf).getServerSession().getDatasourcePlatform();
        // Pessimistic locking with query row limits is not supported on Oracle
        Assume.assumeFalse("Platform " + platform + " is not supported for this test", platform.isOracle());

        EntityManager em = emf.createEntityManager();
        try {
            em.getTransaction().begin();
            List<LockingDog> dogs = em.createNamedQuery("find.lockingdogs", LockingDog.class).
                    setLockMode(LockModeType.PESSIMISTIC_READ).setMaxResults(5).getResultList();
            Assert.assertEquals(5, dogs.size());

            dogs = em.createNamedQuery("find.lockingdogs", LockingDog.class).
                    setFirstResult(1).setMaxResults(5).getResultList();
            Assert.assertEquals(5, dogs.size());
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
        }
    }

    @Test
    public void testFirstResultMaxResultPessimisticRead() {
        Platform platform = ((EntityManagerFactoryImpl) emf).getServerSession().getDatasourcePlatform();
        // Pessimistic locking with query row limits is not supported on Oracle
        Assume.assumeFalse("Platform " + platform + " is not supported for this test", platform.isOracle());

        EntityManager em = emf.createEntityManager();
        try {
            em.getTransaction().begin();
            List<LockingDog> dogs = em.createNamedQuery("find.lockingdogs", LockingDog.class).
                    setLockMode(LockModeType.PESSIMISTIC_READ).setFirstResult(5).setMaxResults(5).getResultList();
            Assert.assertEquals(5, dogs.size());
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }
        }
    }

    /**
     * This test verifies that aggregate queries will not fail with locking
     * set.
     *
     * @see
     *      org.eclipse.persistence.testing.tests.jpa.jpql.AdvancedQueryTestSuite
     *      .testQueryPESSIMISTIC_FORCE_INCREMENTLock()
     */
    @Test
    public void testAggregateResultPessimisticForceIncrement() {
        Platform platform = ((EntityManagerFactoryImpl) emf).getServerSession().getDatasourcePlatform();
        // ORA-01786: FOR UPDATE of this query expression is not allowed
        Assume.assumeFalse("Platform " + platform + " is not supported for this test", platform.isDerby() || platform.isOracle());

        if (((EntityManagerFactoryImpl) emf).getServerSession().getDatasourcePlatform().isDerby()) {
            return;
        }
        EntityManager em = emf.createEntityManager();
        try {
            em.getTransaction().begin();
            em.createNamedQuery("find.lockingdogs.avg").setLockMode(LockModeType.PESSIMISTIC_FORCE_INCREMENT).getSingleResult();
        } finally {
            em.getTransaction().rollback();
            em.close();
        }
    }

    /**
     * This test verifies that queries that return non-Entity results will not
     * fail up with locking set.
     *
     * @see
     *      org.eclipse.persistence.testing.tests.jpa.jpql.AdvancedQueryTestSuite
     *      .testQueryPESSIMISTIC_FORCE_INCREMENTLock()
     */
    @Test
    public void testObjectQueryPessimisticForceIncrement() {
        EntityManager em = emf.createEntityManager();
        try {
            em.getTransaction().begin();
            em.createNamedQuery("find.lockingdogs.id").setLockMode(LockModeType.PESSIMISTIC_FORCE_INCREMENT).getResultList();
        } finally {
            em.getTransaction().rollback();
            em.close();
        }
    }
}
