/*
 * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. 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:
//     SAP - initial API and implementation

package org.eclipse.persistence.testing.tests.wdf.jpa1.entitymanager;

import static org.junit.Assert.fail;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.FlushModeType;
import jakarta.persistence.Query;
import jakarta.persistence.TransactionRequiredException;

import org.eclipse.persistence.testing.framework.wdf.Bugzilla;
import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Department;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Employee;
import org.eclipse.persistence.testing.models.wdf.jpa1.employee.Review;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Ignore;
import org.junit.Test;

public class TestRefresh extends JPA1Base {

    @Test
    public void testRefreshNew() {
        /*
         * Refresh on an entity that is not under control of the entity manager
         * should throw an IllegalArgumentException.
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        Department dep;
        try {
            id = 1;
            dep = new Department(id, "NEW");
            env.beginTransaction(em);
            try {
                em.refresh(dep);
                flop("refresh did not throw IllegalArgumentException");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            }
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @Bugzilla(bugid = 309681)
    public void testRefreshManagedNew() throws SQLException {
        /*
         * Note: The specification doesn't state explicitly how to behave in
         * this case, so we test our interpretation: - If the entity doesn't
         * exist on the database, nothing is changed - If the entity exists on
         * the database, the data is loaded and the state changes from
         * FOR_INSERT to FOR_UPDATE (in order to avoid errors at flush time)
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        Department dep;
        try {
            // case 2: state MANAGED_NEW, but exists on DB (inserted in
            // different tx)
            id = 12;
            dep = new Department(id, "MANAGED_NEW");
            Department depInserted = new Department(id, "INSERTED");
            env.beginTransaction(em);
            em.persist(dep);
            insertDepartmentIntoDatabase(depInserted);
            verifyExistenceOnDatabase(id);
            // entity is now in state MANAGED_NEW, but record exists on db
            em.refresh(dep);
            checkDepartment(dep, id, "INSERTED"); // this should now be in state
                                                  // MANAGED
            verify(em.contains(dep), "Department is not managed");
            dep.setName("UPDATED");
            env.commitTransactionAndClear(em);
            // verify that updated name present on db
            dep = em.find(Department.class, Integer.valueOf(id));
            checkDepartment(dep, id, "UPDATED");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @Bugzilla(bugid = 309681)
    public void testRefreshManagedNewNotOnDB() throws SQLException {
        /*
         * Note: The specification doesn't state explicitly how to behave in
         * this case, so we test our interpretation: - If the entity doesn't
         * exist on the database, nothing is changed - If the entity exists on
         * the database, the data is loaded and the state changes from
         * FOR_INSERT to FOR_UPDATE (in order to avoid errors at flush time)
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        Department dep;
        try {
            // case 1: state MANAGED_NEW and does not exist on DB
            id = 11;
            dep = new Department(id, "MANAGED_NEW");
            env.beginTransaction(em);
            em.persist(dep); // this is now in state MANAGED_NEW, but not on db
            em.refresh(dep); // nothing should happen
            verify(em.contains(dep), "Department is not managed");
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(id);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testRefreshManaged() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        Department dep;
        Department updatedDep;
        try {
            // case 1: undo own changes
            id = 21;
            dep = new Department(id, "MANAGED");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id)); // this is now in
                                                              // state MANAGED
            dep.setName("UPDATED");
            em.refresh(dep);
            checkDepartment(dep, id, "MANAGED");
            verify(em.contains(dep), "Department is not managed");
            env.commitTransactionAndClear(em);
            // verify that original name present on db
            dep = em.find(Department.class, Integer.valueOf(id));
            checkDepartment(dep, id, "MANAGED");
            // case 2: refresh with data changed on db in a different tx
            id = 22;
            dep = new Department(id, "MANAGED");
            updatedDep = new Department(id, "UPDATED");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id)); // this is now in
                                                              // state MANAGED
            updateDepartmentOnDatabase(updatedDep);
            em.refresh(dep);
            checkDepartment(dep, id, "UPDATED");
            verify(em.contains(dep), "Department is not managed");
            dep.setName("MANAGED");
            env.commitTransactionAndClear(em);
            // verify that original name present on db
            dep = em.find(Department.class, Integer.valueOf(id));
            checkDepartment(dep, id, "MANAGED");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @Bugzilla(bugid = 309681)
    public void testRefreshManagedCheckContains() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        Department dep;
        try {
            // case 3: try to refresh, but record has been deleted on db in a
            // different tx
            /*
             * We expect an EntityNotFoundException. However, the specification
             * does not state explicitly in which state the managed entity
             * should be after the exception. We are going to remove the entity
             * from the persistence context, so it is detached afterwards.
             */
            id = 23;
            dep = new Department(id, "MANAGED");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id)); // this is now in
                                                              // state MANAGED
            deleteDepartmentFromDatabase(id);
            verifyAbsenceFromDatabase(em, id);
            try {
                em.refresh(dep);
                flop("refresh did not throw EntityNotFoundException");
            } catch (EntityNotFoundException e) {
                verify(true, "");
            }
            verify(!em.contains(dep), "entity still managed after EntityNotFoundException");
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    private void doRefreshDeleted(int id, boolean flush) throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            Department dep = new Department(id, "DELETED");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);

            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id));
            em.remove(dep);
            if (flush) {
                em.flush(); // this is now in state DELETE_EXECUTED
                verifyAbsenceFromDatabase(em, id);
            }
            try {
                em.refresh(dep);
                fail("refresh did not throw IllegalArgumentException");
            } catch (IllegalArgumentException e) {
                // expected
            }
            if (env.isTransactionActive(em)) {
                env.rollbackTransactionAndClear(em);
            }
        } finally {
            closeEntityManager(em);
        }
    }

    /*
     * Refreshing an entity in state "removed" should raise an
     * IllegalArgumentException
     */
    @Test
    public void testRefreshDeleted() throws SQLException {
        doRefreshDeleted(31, false);
        doRefreshDeleted(32, true);
    }

    @Test
    public void testRefreshDetached() {
        /*
         * Refresh on a detached entity should throw an
         * IllegalArgumentException.
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        Department dep;
        Department detachedDep;
        try {
            // case 1: entity exists on DB, but not contained in persistence
            // context
            id = 41;
            dep = new Department(id, "DETACHED");
            // firstly, we create a department on the database
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            try {
                em.refresh(dep);
                flop("refresh did not throw IllegalArgumentException");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            }
            env.rollbackTransactionAndClear(em);
            // case 2: entity is contained in persistence context, but object to
            // be merged has different object identity
            // case 2a: state of known object: MANAGED_NEW
            id = 42;
            dep = new Department(id, "MANAGED_NEW");
            detachedDep = new Department(id, "DETACHED");
            env.beginTransaction(em);
            em.persist(dep); // this is now in state new
            try {
                em.refresh(detachedDep); // this object is detached
                flop("refresh did not throw IllegalArgumentException");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            }
            env.rollbackTransactionAndClear(em);
            // case 2b: state of known object: MANAGED
            id = 43;
            dep = new Department(id, "MANAGED");
            detachedDep = new Department(id, "DETACHED");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id)); // this is now in
                                                              // state MANAGED
            try {
                em.refresh(detachedDep); // this object is detached
                flop("refresh did not throw IllegalArgumentException");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            }
            env.rollbackTransactionAndClear(em);
            // case 2c: state of known object: DELETED
            id = 44;
            dep = new Department(id, "DELETED");
            detachedDep = new Department(id, "DETACHED");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id));
            em.remove(dep); // this is now in state DELETED
            try {
                em.refresh(detachedDep); // this object is detached
                flop("refresh did not throw IllegalArgumentException");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            }
            env.rollbackTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testNotAnEntity() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            try {
                em.refresh("Hutzliputz");
                flop("no IllegalArgumentException ");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            } finally {
                env.rollbackTransactionAndClear(em);
            }
            env.beginTransaction(em);
            try {
                em.refresh(null);
                flop("no IllegalArgumentException ");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            } finally {
                env.rollbackTransactionAndClear(em);
            }
        } finally {
            closeEntityManager(em);
        }
    }

    @Ignore
    // @TestProperties(unsupportedEnvironments = {
    // JTANonSharedPCEnvironment.class, ResourceLocalEnvironment.class })
    public void testNoTransaction() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        Department dep;
        try {
            id = 61;
            dep = new Department(id, "NO_TX");
            verify(!env.isTransactionActive(em), "transaction is active, can't execute test");
            try {
                em.refresh(dep);
                flop("refresh did not throw TransactionRequiredException");
            } catch (TransactionRequiredException e) {
                verify(true, "");
            }
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testRefreshManagedWithRelationships() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // case 1: undo own changes
            Department dep = new Department(101, "Evangelists");
            Employee emp = new Employee(102, "First", "Last", dep);
            Review rev1 = new Review(103, Date.valueOf("2006-02-03"), "Code inspection");
            Review rev2 = new Review(104, Date.valueOf("2006-02-04"), "Design review");
            emp.addReview(rev1);
            emp.addReview(rev2);
            env.beginTransaction(em);
            em.persist(dep);
            em.persist(emp);
            em.persist(rev1);
            em.persist(rev2);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            emp = em.find(Employee.class, Integer.valueOf(emp.getId()));
            rev1 = em.find(Review.class, Integer.valueOf(rev1.getId()));
            Review rev3 = new Review(105, Date.valueOf("2006-02-05"), "Test coverage");
            Set<Review> reviews = new HashSet<Review>();
            reviews.add(rev1);
            reviews.add(rev3);
            emp.setReviews(reviews);
            rev1.setReviewText("UPDATED");
            em.refresh(emp);
            verify(em.contains(emp), "Employee is not managed");
            Set<Review> reviewsAfterRefresh = emp.getReviews();
            verify(reviewsAfterRefresh.size() == 2, "Employee contains wrong number of reviews: " + reviewsAfterRefresh.size());
            for (Review rev : reviewsAfterRefresh) {
                int id = rev.getId();
                verify(id == rev1.getId() || id == rev2.getId(), "Employee has wrong review: " + id);
                verify(em.contains(rev), "Review " + id + " is not managed");
            }
            env.commitTransactionAndClear(em);
            // verify that original name present on db
            rev1 = em.find(Review.class, Integer.valueOf(rev1.getId()));
            verify("UPDATED".equals(rev1.getReviewText()), "Rev1 has wrong text: " + rev1.getReviewText());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testTransactionMarkedForRollback() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        Department dep = new Department(111, "dep111");
        try {
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransaction(em);
            em.clear();
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(dep.getId()));
            dep.setName("updated");
            env.markTransactionForRollback(em);
            em.refresh(dep);
            checkDepartment(dep, dep.getId(), "dep111");
            verify(em.contains(dep), "entity not contained in persistence context");
            env.rollbackTransaction(em);
        } finally {
            closeEntityManager(em);
        }
    }

    private void verifyExistenceOnDatabase(int departmentId) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("select ID, NAME from TMP_DEP where ID = ?");
            try {
                stmt.setInt(1, departmentId);
                ResultSet rs = stmt.executeQuery();
                try {
                    verify(rs.next(), "no department with id " + departmentId + " found using JDBC.");
                } finally {
                    rs.close();
                }
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }

    private void verifyAbsenceFromDatabase(EntityManager em, int id) {
        Query query = em.createQuery("SELECT d.id from Department d where d.id = ?1");
        query.setFlushMode(FlushModeType.COMMIT);
        query.setParameter(1, Integer.valueOf(id));
        verify(query.getResultList().size() == 0, "wrong result list size");
    }

    private void deleteDepartmentFromDatabase(int departmentId) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("delete from TMP_DEP where ID = ?");
            try {
                stmt.setInt(1, departmentId);
                stmt.executeUpdate();
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }

    private void insertDepartmentIntoDatabase(Department department) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("insert into TMP_DEP (ID, NAME, VERSION) values (?, ?, ?)");
            try {
                stmt.setInt(1, department.getId());
                stmt.setString(2, department.getName());
                stmt.setShort(3, (short) 0);
                stmt.executeUpdate();
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }

    private void updateDepartmentOnDatabase(Department department) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("update TMP_DEP set NAME = ? where ID = ?");
            try {
                stmt.setString(1, department.getName());
                stmt.setInt(2, department.getId());
                stmt.executeUpdate();
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }

    private void checkDepartment(Department department, int id, String name) {
        verify(department != null, "department is null");
        verify(id == department.getId(), "department has wrong id: " + department.getId());
        verify(name.equals(department.getName()), "department has wrong name: " + department.getName());
    }
}
