/*
 * Copyright (c) 1998, 2021 Oracle 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:
//     Oracle - initial API and implementation from Oracle TopLink

package org.eclipse.persistence.testing.tests.jpa.jpql;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import junit.framework.Test;
import junit.framework.TestSuite;

import jakarta.persistence.Query;
import jakarta.persistence.EntityManager;

import org.eclipse.persistence.testing.models.jpa.advanced.Address;
import org.eclipse.persistence.testing.models.jpa.advanced.Department;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.Jigsaw;
import org.eclipse.persistence.testing.models.jpa.advanced.JigsawPiece;
import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.config.CacheUsage;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator;
import org.eclipse.persistence.testing.models.relationshipmaintenance.Dept;
/**
 * <p>
 * <b>Purpose</b>: Test EJBQL parameter functionality.
 * <p>
 * <b>Description</b>: This class creates a test suite, initializes the database
 * and adds tests to the suite.
 * <p>
 * <b>Responsibilities</b>:
 * <ul>
 * <li> Run tests for EJBQL parameter functionality
 * </ul>
 * @see org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator
 * @see JUnitDomainObjectComparer
 */

public class JUnitJPQLParameterTestSuite extends JUnitTestCase {

    static JUnitDomainObjectComparer comparer; //the global comparer object used in all tests

    public JUnitJPQLParameterTestSuite()
    {
        super();
    }

    public JUnitJPQLParameterTestSuite(String name)
    {
        super(name);
    }

    //This method is run at the start of EVERY test case method
    @Override
    public void setUp()
    {

    }

    //This method is run at the end of EVERY test case method
    @Override
    public void tearDown()
    {
        clearCache();
    }

    //This suite contains all tests contained in this class
    public static Test suite()
    {
        TestSuite suite = new TestSuite();
        suite.setName("JUnitJPQLParameterTestSuite");
        suite.addTest(new JUnitJPQLParameterTestSuite("testSetup"));
        suite.addTest(new JUnitJPQLParameterTestSuite("multipleParameterTest"));
        suite.addTest(new JUnitJPQLParameterTestSuite("updateEnumParameter"));
        suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersCheckCacheTest"));
        suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersDontCheckCacheTest"));
        suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersReversedCheckCacheTest"));
        suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersReversedDontCheckCacheTest"));
        if (! JUnitTestCase.isJPA10()) {
            suite.addTest(new JUnitJPQLParameterTestSuite("emptyParametersForNonParameterizedNamedQueryTest"));
        }
        return suite;
    }

    /**
     * The setup is done as a test, both to record its failure, and to allow execution in the server.
     */
    public void testSetup() {
        clearCache();
        //get session to start setup
        DatabaseSession session = JUnitTestCase.getServerSession();

        //create a new EmployeePopulator
        EmployeePopulator employeePopulator = new EmployeePopulator();

        new AdvancedTableCreator().replaceTables(session);

        //initialize the global comparer object
        comparer = new JUnitDomainObjectComparer();

        //set the session for the comparer to use
        comparer.setSession((AbstractSession)session.getActiveSession());

        //Populate the tables
        employeePopulator.buildExamples();

        //Persist the examples in the database
        employeePopulator.persistExample(session);
    }

    //Test case for selecting employee from the database using parameters
    public void multipleParameterTest()
    {
        EntityManager em = createEntityManager();

        Employee employee = (Employee) (getServerSession().readAllObjects(Employee.class).firstElement());
        Vector expectedResult = new Vector();
        expectedResult.add(employee);

        Query query = em.createQuery("SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = ?1 AND emp.id = ?3");
        query.setParameter(1, employee.getFirstName());
        query.setParameter(3, employee.getId());
        List result = query.getResultList();

        assertTrue("Multiple Parameter Test Case Failed", comparer.compareObjects(result, expectedResult));
    }

    // Test for GF#1123 - UPDATE with JPQL does not handle enums correctly.
    public void updateEnumParameter() {
        if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
            getServerSession().logMessage("Test updateEnumParameter skipped for this platform, "
                    + "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
            return;
        }
        EntityManager em = createEntityManager();

        int nrOfEmps = executeJPQLReturningInt(
            em, "SELECT COUNT(e) FROM Employee e WHERE e.period.endDate IS NULL");

        // test query
        String update = "UPDATE Employee e SET e.status = :status, e.payScale = :payScale WHERE e.period.endDate IS NULL";
        beginTransaction(em);
        try {
            Query q = em.createQuery(update);
            q.setParameter("status", Employee.EmployeeStatus.FULL_TIME);
            q.setParameter("payScale", Employee.SalaryRate.SENIOR);
            int updated = q.executeUpdate();
            assertEquals("wrong number of updated instances", nrOfEmps, updated);

            // check database changes
            Query q2 = em.createQuery(
                "SELECT COUNT(e) FROM Employee e WHERE e.period.endDate IS NULL AND e.status = :status AND e.payScale = :payScale");
            q2.setParameter("status", Employee.EmployeeStatus.FULL_TIME);
            q2.setParameter("payScale", Employee.SalaryRate.SENIOR);
            int nr = ((Number)q2.getSingleResult()).intValue();
            assertEquals("unexpected number of changed values in the database", nrOfEmps, nr);
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
        }
    }

    /** Helper method executing a JPQL query retuning an int value. */
    private int executeJPQLReturningInt(EntityManager em, String jpql)
    {
        Query q = em.createQuery(jpql);
        Object result = q.getSingleResult();
        return ((Number)result).intValue();
    }

    // Bug 344492
    public void emptyParametersForNonParameterizedNamedQueryTest() {
        EntityManager em = createEntityManager();
        assertNotNull(em);
        Query query = em.createNamedQuery("findAllEmployeesOrderById");
        assertNotNull(query);
        Set parameters = query.getParameters();
        assertNotNull(parameters);
        assertEquals("Parameters size should be 0", 0, parameters.size());
    }

    public void testQueryParametersCheckCacheTest() {
        testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE j.id=:jigsawId AND p.id=:jigsawPieceId", true);
    }

    public void testQueryParametersDontCheckCacheTest() {
        testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE j.id=:jigsawId AND p.id=:jigsawPieceId", false);
    }

    public void testQueryParametersReversedCheckCacheTest() {
        testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE p.id=:jigsawPieceId AND j.id=:jigsawId", true);
    }

    public void testQueryParametersReversedDontCheckCacheTest() {
        testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE p.id=:jigsawPieceId AND j.id=:jigsawId", false);
    }

    // EL bug 430042 - pk query parameter binding incorrect
    private void testQueryParametersWithQueryAndCheckCache(String jpqlQueryString, boolean checkCacheOnly) {
        EntityManager em = createEntityManager();
        Jigsaw jigsawTestData = null;
        JigsawPiece jigsawPieceTestData = null;

        try {
            beginTransaction(em);

            jigsawTestData = new Jigsaw();
            jigsawPieceTestData = new JigsawPiece();
            jigsawTestData.addPiece(jigsawPieceTestData);
            em.persist(jigsawTestData);

            commitTransaction(em);
            closeEntityManager(em);

            em = createEntityManager();

            Query query = em.createQuery(jpqlQueryString);
            query.setParameter("jigsawId", jigsawTestData.getId());
            query.setParameter("jigsawPieceId", jigsawPieceTestData.getId());

            if (checkCacheOnly) {
                query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
            }

            JigsawPiece resultPiece = (JigsawPiece) query.getSingleResult();
            assertNotNull("Query Entity should not be null", resultPiece);
            Jigsaw resultJigsaw = resultPiece.getJigsaw();
            assertNotNull("Queried Entity's parent reference should not be null", resultJigsaw);
            assertEquals("Queried Entity should have the same id", jigsawPieceTestData.getId(), resultPiece.getId());
            assertEquals("Queried Entity should reference the same parent Entity", jigsawTestData.getId(), resultJigsaw.getId());
        } finally {
            if (jigsawTestData != null) {
                beginTransaction(em);
                Jigsaw jigsawToRemove = em.find(Jigsaw.class, jigsawTestData.getId());
                em.remove(jigsawToRemove);
                for (JigsawPiece piece : jigsawToRemove.getPieces()) {
                    em.remove(piece);
                }
                commitTransaction(em);
            }
            closeEntityManager(em);
        }
    }

}
