/*
 * Copyright (c) 2011, 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:
//     05/19/2010-2.1 ailitchev - Bug 244124 - Add Nested FetchGroup
package org.eclipse.persistence.testing.tests.jpa.fetchgroups;

import java.util.List;

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

import junit.framework.TestSuite;

import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.queries.FetchGroup;
import org.eclipse.persistence.queries.FetchGroupTracker;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber;

import org.junit.Test;

/**
 * Simple tests to verify the functionality of single level FetchGroup usage
 *
 * @author dclarke
 * @since EclipseLink 2.1
 */
public class SimpleNamedFetchGroupTests extends BaseFetchGroupTests {

    public SimpleNamedFetchGroupTests() {
        super();
    }

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

    public static junit.framework.Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("SimpleNamedFetchGroupTests");

        suite.addTest(new SimpleNamedFetchGroupTests("testSetup"));
        suite.addTest(new SimpleNamedFetchGroupTests("findDefaultFetchGroup"));
        suite.addTest(new SimpleNamedFetchGroupTests("singleResultDefaultFetchGroup"));
        suite.addTest(new SimpleNamedFetchGroupTests("resultListDefaultFetchGroup"));
        suite.addTest(new SimpleNamedFetchGroupTests("singleResultNoFetchGroup"));
        suite.addTest(new SimpleNamedFetchGroupTests("resultListNoFetchGroup"));
        suite.addTest(new SimpleNamedFetchGroupTests("managerFetchGroup"));
        suite.addTest(new SimpleNamedFetchGroupTests("namedEmptyFetchGroupUsingGetSingleResult"));
        suite.addTest(new SimpleNamedFetchGroupTests("namedNamesFetchGroupUsingGetSingleResult"));
        suite.addTest(new SimpleNamedFetchGroupTests("joinFetchEmployeeAddressWithDynamicFetchGroup"));
        suite.addTest(new SimpleNamedFetchGroupTests("joinFetchEmployeeAddressPhoneWithDynamicFetchGroup"));

        return suite;
    }

    @Override
    public void setUp() {
        super.setUp();

        FetchGroup namedEmpFG = new FetchGroup("Employee.test");
        namedEmpFG.addAttribute("firstName");
        namedEmpFG.addAttribute("lastName");
        employeeDescriptor.getFetchGroupManager().addFetchGroup(namedEmpFG);

        FetchGroup namedPhoneFG = new FetchGroup("Phone.test");
        namedPhoneFG.addAttribute("number");
        phoneDescriptor.getFetchGroupManager().addFetchGroup(namedPhoneFG);

        FetchGroup namedAddressFG = new FetchGroup("Address.test");
        namedAddressFG.addAttribute("city");
        addressDescriptor.getFetchGroupManager().addFetchGroup(namedAddressFG);

        assertConfig(employeeDescriptor, null, 1);
        assertConfig(phoneDescriptor, null, 1);
        assertConfig(addressDescriptor, null, 1);
    }

    @Test
    public void findDefaultFetchGroup() throws Exception {
        EntityManager em = createEntityManager();

        Employee emp = minimumEmployee(em);

        assertNotNull(emp);
        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        assertNoFetchGroup(emp);

        emp.getSalary();

        assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        assertNoFetchGroup(emp.getAddress());
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        for (PhoneNumber phone : emp.getPhoneNumbers()) {
            assertNoFetchGroup(phone);
        }

        int nSqlExpected = 3;
        if (usesSOP()) {
            // When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
            nSqlExpected--;
        }
        assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        if (emp.getManager() != null) {
            assertNoFetchGroup(emp.getManager());
            assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } else {
            // If manager_id field is null then getManager() does not trigger an sql.
            assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        }
    }

    @Test
    public void singleResultDefaultFetchGroup() throws Exception {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
        query.setParameter("ID", minimumEmployeeId(em));

        Employee emp = (Employee) query.getSingleResult();

        assertNotNull(emp);
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        assertNoFetchGroup(emp);

        emp.getSalary();

        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        assertNoFetchGroup(emp.getAddress());
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        for (PhoneNumber phone : emp.getPhoneNumbers()) {
            assertNoFetchGroup(phone);
        }

        int nSqlExpected = 4;
        if (usesSOP()) {
            // When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
            nSqlExpected--;
        }
        assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        if (emp.getManager() != null) {
            assertNoFetchGroup(emp.getManager());
            assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } else {
            // If manager_id field is null then getManager() does not trigger an sql.
            assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        }
    }

    @Test
    public void resultListDefaultFetchGroup() throws Exception {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
        query.setParameter("ID", minimumEmployeeId(em));

        List<Employee> emps = query.getResultList();

        assertNotNull(emps);
        assertEquals(1, emps.size());

        Employee emp = emps.get(0);

        assertNotNull(emp);
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        assertNoFetchGroup(emp);

        emp.getSalary();

        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        assertNoFetchGroup(emp.getAddress());
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        for (PhoneNumber phone : emp.getPhoneNumbers()) {
            assertNoFetchGroup(phone);
        }

        int nSqlExpected = 4;
        if (usesSOP()) {
            // When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
            nSqlExpected--;
        }
        assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        if (emp.getManager() != null) {
            assertNoFetchGroup(emp.getManager());
            assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } else {
            // If manager_id field is null then getManager() does not trigger an sql.
            assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        }
    }

    @Test
    public void singleResultNoFetchGroup() throws Exception {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
        query.setParameter("ID", minimumEmployeeId(em));

        Employee emp = (Employee) query.getSingleResult();

        assertNotNull(emp);
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        assertNoFetchGroup(emp);

        emp.getSalary();

        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        assertNoFetchGroup(emp.getAddress());
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        for (PhoneNumber phone : emp.getPhoneNumbers()) {
            assertNoFetchGroup(phone);
        }

        int nSqlExpected = 4;
        if (usesSOP()) {
            // When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
            nSqlExpected--;
        }
        assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        if (emp.getManager() != null) {
            assertNoFetchGroup(emp.getManager());
            assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } else {
            // If manager_id field is null then getManager() does not trigger an sql.
            assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        }
    }

    @Test
    public void resultListNoFetchGroup() throws Exception {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
        query.setParameter("ID", minimumEmployeeId(em));

        List<Employee> emps = query.getResultList();

        assertNotNull(emps);
        assertEquals(1, emps.size());

        Employee emp = emps.get(0);

        assertNotNull(emp);
        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        assertNoFetchGroup(emp);

        emp.getSalary();

        assertEquals(2, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        assertNoFetchGroup(emp.getAddress());
        assertEquals(3, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        for (PhoneNumber phone : emp.getPhoneNumbers()) {
            assertNoFetchGroup(phone);
        }

        int nSqlExpected = 4;
        if (usesSOP()) {
            // When SOP is used PhoneNumbers are read in sopObject when the fetch group is triggered, so one less sql.
            nSqlExpected--;
        }
        assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

        if (emp.getManager() != null) {
            assertNoFetchGroup(emp.getManager());
            assertEquals(++nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } else {
            // If manager_id field is null then getManager() does not trigger an sql.
            assertEquals(nSqlExpected, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        }
    }

    @Override
    @Test
    public void managerFetchGroup() throws Exception {
        EntityManager em = createEntityManager();
        try {
            beginTransaction(em);
            // Use q query since find will only use default fetch group
            // Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
            // query.setParameter("ID", minimumEmployeeId(em));

            // Complex where clause used to avoid triggering employees and their departments:
            //   Don't include employees who are managers themselves - otherwise if first selected as employee, then as e.manager the full read will be triggered;
            //   Don't include managers with departments - because there is no fetch group on e.manager its (non-null) department will trigger an extra sql
            Query query = em.createQuery("SELECT e FROM Employee e WHERE e.manager IS NOT NULL AND NOT EXISTS(SELECT e2 FROM Employee e2 WHERE e2.manager = e) AND e.manager.department IS NULL");
            FetchGroup managerFG = new FetchGroup();
            managerFG.addAttribute("manager");

            query.setHint(QueryHints.FETCH_GROUP, managerFG);

            assertNotNull(getFetchGroup(query));
            assertSame(managerFG, getFetchGroup(query));

            Employee emp = (Employee) query.getSingleResult();

            assertFetched(emp, managerFG);
            assertEquals(1, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            int nSqlToAdd = 0;
            if (emp.getManager() != null) {
                assertFetchedAttribute(emp, "manager");
                // additional sql to select the manager
                nSqlToAdd++;
            }

            assertEquals(1 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());

            // instantiates the whole object
            emp.getLastName();

            assertEquals(2 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
            assertNoFetchGroup(emp);

            for (PhoneNumber phone : emp.getPhoneNumbers()) {
                assertNoFetchGroup(phone);
            }

            assertEquals(3 + nSqlToAdd, getQuerySQLTracker(em).getTotalSQLSELECTCalls());
        } finally {
            if (isTransactionActive(em)){
                rollbackTransaction(em);
            }
            closeEntityManager(em);
        }
    }

    @Test
    public void namedEmptyFetchGroupUsingGetSingleResult() throws Exception {
        ClassDescriptor descriptor = getDescriptor("Employee");

        FetchGroup fetchGroup = new FetchGroup("test");
        descriptor.getFetchGroupManager().addFetchGroup(fetchGroup);
        assertTrue(fetchGroup.getItems().isEmpty());

        assertEquals(2, descriptor.getFetchGroupManager().getFetchGroups().size());

        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
        query.setParameter("ID", minimumEmployeeId(em));
        query.setHint(QueryHints.FETCH_GROUP_NAME, "test");

        Employee emp = (Employee) query.getSingleResult();
        assertNotNull(emp);

        FetchGroupTracker tracker = (FetchGroupTracker) emp;
        assertNotNull(tracker);

        FetchGroup usedFG = tracker._persistence_getFetchGroup();

        assertNotNull("No FetchGroup found on read Employee", usedFG);
        // No longer can make any assumptions about a name of FetchGroup on the entity
        // What's guaranteed is that attribute sets are the same
        assertTrue(fetchGroup.getAttributeNames().equals(usedFG.getAttributeNames()));
//        assertEquals(fetchGroup.getName(), usedFG.getName());
//        assertSame(fetchGroup, ((EntityFetchGroup) usedFG).getParent());
        assertEquals(2, fetchGroup.getItems().size());
        assertTrue(tracker._persistence_isAttributeFetched("id"));
        assertTrue(tracker._persistence_isAttributeFetched("version"));
        assertFalse(tracker._persistence_isAttributeFetched("salary"));
        assertFalse(tracker._persistence_isAttributeFetched("firstName"));
        assertFalse(tracker._persistence_isAttributeFetched("lastName"));
    }

    @Test
    public void namedNamesFetchGroupUsingGetSingleResult() throws Exception {
        ClassDescriptor descriptor = getDescriptor("Employee");

        FetchGroup fetchGroup = new FetchGroup("names");
        fetchGroup.addAttribute("firstName");
        fetchGroup.addAttribute("lastName");

        descriptor.getFetchGroupManager().addFetchGroup(fetchGroup);
        assertEquals(2, fetchGroup.getItems().size());

        assertEquals(2, descriptor.getFetchGroupManager().getFetchGroups().size());

        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
        query.setParameter("ID", minimumEmployeeId(em));
        query.setHint(QueryHints.FETCH_GROUP_NAME, "names");

        Employee emp = (Employee) query.getSingleResult();
        assertNotNull(emp);

        FetchGroupTracker tracker = (FetchGroupTracker) emp;
        assertNotNull(tracker);

        FetchGroup usedFG = tracker._persistence_getFetchGroup();

        assertNotNull("No FetcGroup found on read Employee", fetchGroup);
//        assertSame(fetchGroup, ((EntityFetchGroup) usedFG).getParent());
        assertEquals(4, fetchGroup.getItems().size());
        assertTrue(tracker._persistence_isAttributeFetched("id"));
        assertTrue(tracker._persistence_isAttributeFetched("version"));
        assertFalse(tracker._persistence_isAttributeFetched("salary"));
        assertTrue(tracker._persistence_isAttributeFetched("firstName"));
        assertTrue(tracker._persistence_isAttributeFetched("lastName"));
    }

    @Override
    @Test
    public void joinFetchEmployeeAddressWithDynamicFetchGroup() {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address");

        FetchGroup fetchGroup = new FetchGroup("names");
        fetchGroup.addAttribute("firstName");
        fetchGroup.addAttribute("lastName");
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);

        List<Employee> emps = query.getResultList();

        assertNotNull(emps);
    }

    @Override
    @Test
    public void joinFetchEmployeeAddressPhoneWithDynamicFetchGroup() {
        EntityManager em = createEntityManager();

        Query query = em.createQuery("SELECT e FROM Employee e JOIN FETCH e.address WHERE e.id IN (SELECT p.id FROM PhoneNumber p)");

        FetchGroup fetchGroup = new FetchGroup("names");
        fetchGroup.addAttribute("firstName");
        fetchGroup.addAttribute("lastName");
        query.setHint(QueryHints.FETCH_GROUP, fetchGroup);

        List<Employee> emps = query.getResultList();

        assertNotNull(emps);
    }
}
