/*
 * 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 java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import jakarta.persistence.EntityExistsException;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.TransactionRequiredException;

import org.junit.Assert;

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.timestamp.Nasty;
import org.eclipse.persistence.testing.models.wdf.jpa1.timestamp.Timestamp;
import org.eclipse.persistence.testing.models.wdf.jpa1.types.BasicTypesFieldAccess;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Ignore;
import org.junit.Test;



public class TestPersist extends JPA1Base {

    private void verifyExistenceOnDatabase(int departmentId, String tableName) throws SQLException {
        if (tableName == null || !tableName.startsWith("TMP_")) {
            throw new IllegalArgumentException(
                    "None or illegal tableName was submitted to this method. Valid tableNames have to begin with 'TMP_'.");
        }
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            StringBuilder builder = new StringBuilder();
            builder.append("select ID from ").append(tableName).append(" where ID = ?");
            PreparedStatement stmt = conn.prepareStatement(builder.toString());
            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();
        }
    }

    @Test
    public void testPersistNewDepartment() throws SQLException {
        /*
         * If X is a new entity, it becomes managed. The entity X will be entered into the database at or before transaction
         * commit or as a result of the flush operation.
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            Department dep = new Department(1, "R&D");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            // verify existence after commit
            verifyExistenceOnDatabase(1, "TMP_DEP");
            Department dep2 = new Department(2, "QM");
            env.beginTransaction(em);
            em.persist(dep2);
            em.flush();
            // will not work on Oracle!
            // verify existence after flush
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(2, "TMP_DEP");
            // TODO verify cascading
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testPersistNewBasicTypesFieldAccess() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            BasicTypesFieldAccess btfa = new BasicTypesFieldAccess(1);
            btfa.fill();
            env.beginTransaction(em);
            em.persist(btfa);
            env.commitTransactionAndClear(em);
            // verify existence after commit
            verifyExistenceOnDatabase(1, "TMP_BASIC_TYPES_FA");
            BasicTypesFieldAccess btfa2 = new BasicTypesFieldAccess(2);
            btfa2.fill();
            env.beginTransaction(em);
            em.persist(btfa2);
            em.flush();
            // will not work on Oracle!
            // verify existence after flush
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(2, "TMP_BASIC_TYPES_FA");
            // TODO verify cascading
        } finally {
            closeEntityManager(em);
        }
    }

    private void verifyPersistManaged(boolean flushBeforePersist) {
        /*
         * If X is a pre-existing managed entity, it is ignored by the persist operation. However, the persist operation is
         * cascaded to entities referenced by X, if the relationships from X to these other entities is annotated with the
         * cascade=PERSIST or cascade=ALL annotation element value or specified with the equivalent XML descriptor element.
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // 1. managed via find
            final int id1 = (flushBeforePersist ? 100 : 0) + 11;
            Department dep = new Department(id1, "OLD");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            // find a department in the state MANAGED
            dep = em.find(Department.class, Integer.valueOf(id1));
            verify(dep != null, "department not found");
            dep.setName("CHANGED");
            if (flushBeforePersist) {
                em.flush();
            }
            // this persist should be ignored as object is already managed
            em.persist(dep);
            // TODO verify that persist is ignored (use callback methods)
            // TODO verify cascading
            env.commitTransactionAndClear(em);
            // 2. managed via persist
            final int id2 = (flushBeforePersist ? 100 : 0) + 12;
            dep = new Department(id2, "OLD");
            env.beginTransaction(em);
            em.persist(dep);
            dep.setName("CHANGED");
            if (flushBeforePersist) {
                em.flush();
            }
            // this persist should be ignored as object is already managed
            em.persist(dep);
            // TODO verify that persist is ignored (use callback methods)
            // TODO verify cascading
            env.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    private void verifyPersistRemoved(boolean flushBeforePersist) {
        /*
         * If X is a removed entity, it becomes managed.
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // 1. find an existing department, remove it and call persist
            final int id1 = (flushBeforePersist ? 100 : 0) + 21;
            Department dep = new Department(id1, "REMOVE");
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);

            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id1));
            em.remove(dep);
            // now, the entity should be REMOVED
            if (flushBeforePersist) {
                em.flush();
            }
            em.persist(dep);
            // now, the entity should be managed again
            dep.setName("REINVIGORATED");
            env.commitTransactionAndClear(em);

            dep = em.find(Department.class, Integer.valueOf(id1));
            verify(dep != null, "department not found");
            verify("REINVIGORATED".equals(dep.getName()), "department has wrong name: " + dep.getName());

            // 2. persist a new department, remove it and call persist
            env.beginTransaction(em);
            final int id2 = (flushBeforePersist ? 100 : 0) + 22;
            dep = new Department(id2, "REMOVE");
            em.persist(dep);
            em.remove(dep);
            if (flushBeforePersist) {
                em.flush();
            }
            em.persist(dep);
            dep.setName("REINVIGORATED");
            env.commitTransactionAndClear(em);

            dep = em.find(Department.class, Integer.valueOf(id2));
            verify(dep != null, "department not found");
            verify("REINVIGORATED".equals(dep.getName()), "department has wrong name: " + dep.getName());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testPersistManaged() {
        verifyPersistManaged(false);
    }

    @Test
    public void testPersistManagedFlushed() {
        verifyPersistManaged(true);
    }

    @Test
    public void testPersistRemoved() {
        verifyPersistRemoved(false);
    }

    @Test
    public void testPersistRemovedFlushed() {
        verifyPersistRemoved(true);
    }

    @Test
    public void testPersistDetached() throws SQLException {
        /*
         * <li>If X is a detached object, the EntityExistsException may be thrown when the persist operation is invoked,
         * or the EntityExistsException or another PersistenceException may be thrown at flush or commit time.</li>
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        try {
            // case 1: detached because entity exists on db but is not known by persistence context
            id = 31;
            Department dep = new Department(id, "DETACHED");
            // firstly, we create a department on the database
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(id, "TMP_DEP");
            // now, the department is detached, we try to persist it again
            env.beginTransaction(em);
            boolean failed = false;
            try {
                em.persist(dep);
            } catch (EntityExistsException e) {
                failed = true;
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForPersistenceException(e)) {
                    throw e;
                }
                failed = true;
            }
            verify(failed, "persist did succeed on a detached instance.");
            // case 2: detached because an object with same pk but different object identity is known by persistence context
            // case 2a: state of known object: FOR_INSERT
            id = 32;
            dep = new Department(id, "ORIGINAL");
            Department detachedDep = new Department(id, "DETACHED");
            failed = false;
            env.beginTransaction(em);
            em.persist(dep); // this is now in state new
            try {
                em.persist(detachedDep);
            } catch (EntityExistsException e) {
                failed = true;
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForPersistenceException(e)) {
                    throw e;
                }
                failed = true;
            }
            verify(failed, "persist did succeed on a detached instance.");
            // case 2b: state of known object: FOR_UPDATE
            id = 33;
            dep = new Department(id, "ORIGINAL");
            detachedDep = new Department(id, "DETACHED");
            failed = false;
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(id, "TMP_DEP");
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id)); // this is now in state managed
            try {
                em.persist(detachedDep);
            } catch (EntityExistsException e) {
                failed = true;
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForPersistenceException(e)) {
                    throw e;
                }
                failed = true;
            }
            verify(failed, "persist did succeed on a detached instance.");
            // case 2c: state of known object: FOR_DELETE
            id = 34;
            dep = new Department(id, "ORIGINAL");
            detachedDep = new Department(id, "DETACHED");
            failed = false;
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(id, "TMP_DEP");
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id));
            em.remove(dep); // this is now in state deleted
            try {
                em.persist(detachedDep);
            } catch (EntityExistsException e) {
                failed = true;
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForPersistenceException(e)) {
                    throw e;
                }
                failed = true;
            }
            verify(failed, "persist did succeed on a detached instance.");
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @Bugzilla(bugid=309681)
    public void testPersistDeleteExecuted() throws SQLException {
        /*
         * If X is a detached object, an IllegalArgumentException will be thrown by the persist operation (or the transaction
         * commit will fail).
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        int id;
        try {
            // case 2d: state of known object: DELETE_EXECUTED
            id = 35;
            Department dep = new Department(id, "ORIGINAL");
            Department detachedDep = new Department(id, "DETACHED");
            boolean failed = false;
            env.beginTransaction(em);
            em.persist(dep);
            env.commitTransactionAndClear(em);
            verifyExistenceOnDatabase(id, "TMP_DEP");
            env.beginTransaction(em);
            dep = em.find(Department.class, Integer.valueOf(id));
            em.remove(dep);
            em.flush();
            try {
                em.persist(detachedDep);
            } catch (IllegalArgumentException e) {
                failed = true;
                env.rollbackTransactionAndClear(em);
            }
            try {
                if (env.isTransactionActive(em)) {
                    env.commitTransactionAndClear(em);
                }
            } catch (RuntimeException e) {
                if (!checkForPersistenceException(e)) {
                    throw e;
                }
                failed = true;
            }
            verify(failed, "persist did succeed on a detached instance.");
        } finally {
            closeEntityManager(em);
        }
    }

    /*
     * throws IllegalArgumentException, if instance is not an entity
     */
    @Test
    public void testNotAnEntity() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            try {
                em.persist("Hutzliputz");
                flop("no IllegalArgumentException ");
            } catch (IllegalArgumentException e) {
                verify(true, "");
            } finally {
                env.rollbackTransactionAndClear(em);
            }
            env.beginTransaction(em);
            try {
                em.persist(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();
        Department dep = new Department(41, "dep41");
        try {
            em.persist(dep);
            flop("exception not thrown as expected");
        } catch (TransactionRequiredException e) {
            // $JL-EXC$ expected behavior
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testTransactionMarkedForRollback() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // case 1: persistence context already available when tx marked for rollback
            Department dep = new Department(42, "dep42");
            env.beginTransaction(em);
            verify(!em.contains(dep), "entity contained in persistence context"); // this ensures that the pc is available
            env.markTransactionForRollback(em);
            em.persist(dep);
            verify(em.contains(dep), "entity not contained in persistence context");
            env.rollbackTransaction(em);
            // case 2: persistence context not yet available when tx marked for rollback
            // will throw an exception in the container-managed JTA case
            if (!(env instanceof /* JTASharedPCEnvironment */Object)) {
                dep = new Department(43, "dep43");
                env.beginTransaction(em);
                env.markTransactionForRollback(em);
                em.persist(dep);
                verify(em.contains(dep), "entity not contained in persistence context");
                env.rollbackTransaction(em);
            }
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testPersistNewEntityWithIdModifiedInPrePersist() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            Timestamp timestamp = new Timestamp();
            verify(timestamp.getId() == null, "id is not null");
            env.beginTransaction(em);
            em.persist(timestamp);
            Long value = timestamp.getId();
            verify(value != null, "id is null");
            env.commitTransactionAndClear(em);
            verify(em.find(Timestamp.class, value) != null, "not found");
        } finally {
            closeEntityManager(em);
        }
    }

    private void verifyPersistRemovedEntityWithIdModifiedInPrePersist(boolean removeExecuted) {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            Timestamp timestamp = new Timestamp();
            verify(timestamp.getId() == null, "id is not null");
            env.beginTransaction(em);
            em.persist(timestamp);
            env.commitTransaction(em);

            env.beginTransaction(em);
            final Long id1 = timestamp.getId();
            timestamp = em.find(Timestamp.class, id1);
            em.remove(timestamp);
            if (removeExecuted) {
                em.flush();
            }

            em.persist(timestamp);

            env.commitTransactionAndClear(em);
            final Long id2 = timestamp.getId();

            Assert.assertFalse(id2.equals(id1));

            Assert.assertNull(em.find(Timestamp.class, id1));
            Assert.assertNotNull(em.find(Timestamp.class, id1));


        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @Bugzilla(bugid=309681)
    public void testPersistRemovedEntityWithIdModifiedInPrePersist() {
        verifyPersistRemovedEntityWithIdModifiedInPrePersist(false);
    }

    @Test
    @Bugzilla(bugid=309681)
    public void testPersistRemovedEntityWithIdModifiedInPrePersistFlushed() {
        verifyPersistRemovedEntityWithIdModifiedInPrePersist(true);
    }

    @Test
    public void testNastyTimestampTwice() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            Nasty nasty = new Nasty();
            verify(nasty.getId() == null, "id is not null");
            env.beginTransaction(em);
            em.persist(nasty);
            Long value = nasty.getId();
            verify(value != null, "id is null");
            try {
                em.persist(new Nasty());
                env.commitTransaction(em);
                flop("persisting second nasty timestamp succeeded");
            } catch (PersistenceException ex) {
                Assert.assertTrue(true);
            }
            if (env.isTransactionActive(em)) {
                env.rollbackTransactionAndClear(em);
            }
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testDuprec() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Department department = new Department(999, "X");
            em.persist(department);
            env.commitTransactionAndClear(em);

            env.beginTransaction(em);
            try {
                em.persist(department); // exception here
                env.commitTransaction(em); // or here
                flop("duprec not detected");
            } catch (PersistenceException ex) {
                // OK
            } catch (/* JTARollback */Exception ex) {
                // JTA OK
            }
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testDuprecBatch() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            env.beginTransaction(em);
            Department d1 = new Department(998, "X");
            em.persist(d1);
            Department d2 = new Department(997, "X");
            em.persist(d2);
            Department d3 = new Department(996, "X");
            em.persist(d3);
            Department d4 = new Department(995, "X");
            em.persist(d4);
            Department d5 = new Department(994, "X");
            em.persist(d5);
            env.commitTransactionAndClear(em);

            env.beginTransaction(em);
            try {
                d1 = new Department(993, "X");
                em.persist(d1);
                d2 = new Department(992, "X");
                em.persist(d2);
                d3 = new Department(991, "X");
                em.persist(d3);
                em.persist(d4); // duprec: 995
                d5 = new Department(990, "X");
                em.persist(d5);
                env.commitTransaction(em); // or here
                flop("duprec not detected");
            } catch (PersistenceException ex) {
                // OK
            } catch (/* JTARollback */Exception ex) {
                // JTA OK
            }
        } finally {
            closeEntityManager(em);
        }
    }

}
