/*
 * 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.EntityManager;

import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated;
import org.eclipse.persistence.testing.models.wdf.jpa1.node.CascadingNode;
import org.eclipse.persistence.testing.models.wdf.jpa1.node.CascadingNodeDescription;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

/*
 * A managed entity instance becomes removed by invoking the remove method on it or by cascading the remove operation. The
 * semantics of the remove operation, applied to an entity X are as follows:
 * <ul>
 * <li>If X is a new entity, it is ignored by the remove operation. However, the remove operation is cascaded to entities
 * referenced by X, if the relationships from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL
 * annotation element value.</li>
 * <li>If X is a managed entity, the remove operation causes it to become removed. The remove operation is cascaded to entities
 * referenced by X, if the relationships from X to these other entities is annotated with the cascade=REMOVE or cascade=ALL
 * annotation element value.</li>
 * <li>If X is a detached entity, an IllegalArgumentException will be thrown by the remove operation (or the transaction commit
 * will fail).</li>
 * <li>If X is a removed entity, it is ignored by the remove operation.</li>
 * <li>A removed entity X will be removed from the database at or before transaction commit or as a result of the flush
 * operation.</li>
 * </ul>
 * After an entity has been removed, its state (except for generated state) will be that of the entity at the point at which the
 * remove operation was called.
 */
public class TestCascadeRemove extends JPA1Base {

    @Test
    public void testSimpleCascadeNew() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        env.evictAll(em);
        try {
            // one-to-many relationship
            CascadingNode child = new CascadingNode(1, null);
            env.beginTransaction(em);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            child = em.find(CascadingNode.class, child.getId());
            CascadingNode parent = new CascadingNode(2, null);
            parent.addChild(child);
            verify(!em.contains(parent), "Parent not a new entity");
            verify(em.contains(child), "Child not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyAbsenceFromNodeTable(child.getId());
            // one-to-one relationship
            CascadingNodeDescription description = new CascadingNodeDescription(3, null, "a simple node");
            env.beginTransaction(em);
            em.persist(description);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            description = em.find(CascadingNodeDescription.class, description.getId());
            parent = new CascadingNode(4, null);
            parent.setDescription(description);
            description.setNode(parent);
            verify(!em.contains(parent), "Parent not a new entity");
            verify(em.contains(description), "Description not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyAbsenceFromDescriptionTable(description.getId());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testSimpleCascadeManaged() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // Case 1: status FOR_INSERT
            // one-to-many relationship
            CascadingNode child = new CascadingNode(101, null);
            env.beginTransaction(em);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            CascadingNode parent = new CascadingNode(102, null);
            em.persist(parent);
            child = em.find(CascadingNode.class, child.getId());
            parent.addChild(child);
            verify(em.contains(parent), "Parent not managed");
            verify(em.contains(child), "Child not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyAbsenceFromNodeTable(child.getId());
            // one-to-one relationship
            CascadingNodeDescription description = new CascadingNodeDescription(103, null, "a simple node");
            env.beginTransaction(em);
            em.persist(description);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            parent = new CascadingNode(104, null);
            em.persist(parent);
            description = em.find(CascadingNodeDescription.class, description.getId());
            parent.setDescription(description);
            description.setNode(parent);
            verify(em.contains(parent), "Parent not managed");
            verify(em.contains(description), "Description not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyAbsenceFromDescriptionTable(description.getId());
            // Case 2: status FOR_UPDATE
            // one-to-many relationship
            parent = new CascadingNode(105, null);
            child = new CascadingNode(106, null);
            env.beginTransaction(em);
            em.persist(parent);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            parent = em.find(CascadingNode.class, parent.getId());
            child = em.find(CascadingNode.class, child.getId());
            parent.addChild(child);
            verify(em.contains(parent), "Parent not managed");
            verify(em.contains(child), "Child not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyAbsenceFromNodeTable(child.getId());
            // one-to-one relationship
            parent = new CascadingNode(107, null);
            description = new CascadingNodeDescription(108, parent, "a simple node");
            parent.setDescription(description);
            env.beginTransaction(em);
            em.persist(parent);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            parent = em.find(CascadingNode.class, parent.getId());
            description = parent.getDescription();
            verify(em.contains(parent), "Parent not managed");
            verify(em.contains(description), "Description not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyAbsenceFromDescriptionTable(description.getId());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testSimpleCascadeDetached() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // Case 1: detached because entity exists on db but is not known by persistence context
            // one-to-many relationship
            CascadingNode parent = new CascadingNode(201, null);
            CascadingNode child = new CascadingNode(202, null);
            env.beginTransaction(em);
            em.persist(parent);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            child = em.find(CascadingNode.class, child.getId());
            parent.addChild(child);
            verify(!em.contains(parent), "Parent not detached");
            verify(em.contains(child), "Child not managed");
            boolean removeFailed = false;
            boolean immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(child), "Child is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (!checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyExistenceInNodeTable(parent.getId());
            verifyExistenceInNodeTable(child.getId());
            // one-to-one relationship
            parent = new CascadingNode(203, null);
            CascadingNodeDescription description = new CascadingNodeDescription(204, null, "a simple node");
            env.beginTransaction(em);
            em.persist(parent);
            em.persist(description);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            description = em.find(CascadingNodeDescription.class, description.getId());
            parent.setDescription(description);
            verify(!em.contains(parent), "Parent not detached");
            verify(em.contains(description), "Description not managed");
            removeFailed = false;
            immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(description), "Description is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (!checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyExistenceInNodeTable(parent.getId());
            verifyExistenceInDescriptionTable(description.getId());
            // 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
            // one-to-many relationship
            CascadingNode existing = new CascadingNode(205, null);
            parent = new CascadingNode(existing.getId(), null);
            child = new CascadingNode(206, null);
            env.beginTransaction(em);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            em.persist(existing); // status FOR_INSERT
            child = em.find(CascadingNode.class, child.getId());
            parent.addChild(child);
            verify(!em.contains(parent), "Parent not detached");
            verify(em.contains(existing), "Existing not managed");
            verify(em.contains(child), "Child not managed");
            removeFailed = false;
            immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(child), "Child is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            verify(em.contains(existing), "Previously managed entity no longer managed");
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (immediateException || !checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyAbsenceFromNodeTable(existing.getId());
            verifyExistenceInNodeTable(child.getId());
            // one-to-one relationship
            existing = new CascadingNode(207, null);
            parent = new CascadingNode(existing.getId(), null);
            description = new CascadingNodeDescription(208, null, "some text");
            env.beginTransaction(em);
            em.persist(description);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            em.persist(existing); // status FOR_INSERT
            description = em.find(CascadingNodeDescription.class, description.getId());
            parent.setDescription(description);
            verify(!em.contains(parent), "Parent not detached");
            verify(em.contains(existing), "Existing not managed");
            verify(em.contains(description), "Description not managed");
            removeFailed = false;
            immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(description), "Description is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            verify(em.contains(existing), "Previously managed entity no longer managed");
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (immediateException || !checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyAbsenceFromNodeTable(existing.getId());
            verifyExistenceInNodeTable(child.getId());
            // Case 2b: state of known object: FOR_UPADTE
            // one-to-many relationship
            existing = new CascadingNode(209, null);
            parent = new CascadingNode(existing.getId(), null);
            child = new CascadingNode(210, null);
            env.beginTransaction(em);
            em.persist(existing);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            existing = em.find(CascadingNode.class, existing.getId()); // state FOR_UPADTE
            child = em.find(CascadingNode.class, child.getId());
            parent.addChild(child);
            verify(!em.contains(parent), "Parent not detached");
            verify(em.contains(existing), "Existing not managed");
            verify(em.contains(child), "Child not managed");
            removeFailed = false;
            immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(child), "Child is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            verify(em.contains(existing), "Previously managed entity no longer managed");
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (!checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyExistenceInNodeTable(existing.getId());
            verifyExistenceInNodeTable(child.getId());
            // one-to-one relationship
            existing = new CascadingNode(211, null);
            parent = new CascadingNode(existing.getId(), null);
            description = new CascadingNodeDescription(212, null, "some text");
            env.beginTransaction(em);
            em.persist(existing);
            em.persist(description);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            existing = em.find(CascadingNode.class, existing.getId()); // state FOR_UPADTE
            description = em.find(CascadingNodeDescription.class, description.getId());
            parent.setDescription(description);
            verify(!em.contains(parent), "Parent not detached");
            verify(em.contains(existing), "Existing not managed");
            verify(em.contains(description), "Description not managed");
            removeFailed = false;
            immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(description), "Description is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            verify(em.contains(existing), "Previously managed entity no longer managed");
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (!checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyExistenceInNodeTable(existing.getId());
            verifyExistenceInDescriptionTable(description.getId());
            // Case 2c: state of known object: FOR_REMOVE
            // one-to-many relationship
            existing = new CascadingNode(213, null);
            parent = new CascadingNode(existing.getId(), null);
            child = new CascadingNode(214, null);
            env.beginTransaction(em);
            em.persist(existing);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            existing = em.find(CascadingNode.class, existing.getId());
            em.remove(existing); // state FOR_REMOVE
            child = em.find(CascadingNode.class, child.getId());
            parent.addChild(child);
            verify(!em.contains(parent), "Parent not detached");
            verify(!em.contains(existing), "Existing not removed");
            verify(em.contains(child), "Child not managed");
            removeFailed = false;
            immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(child), "Child is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (!checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyExistenceInNodeTable(existing.getId());
            verifyExistenceInNodeTable(child.getId());
            // one-to-one relationship
            existing = new CascadingNode(215, null);
            parent = new CascadingNode(existing.getId(), null);
            description = new CascadingNodeDescription(216, null, "some text");
            env.beginTransaction(em);
            em.persist(existing);
            em.persist(description);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            existing = em.find(CascadingNode.class, existing.getId());
            em.remove(existing); // state FOR_REMOVE
            description = em.find(CascadingNodeDescription.class, description.getId());
            parent.setDescription(description);
            verify(!em.contains(parent), "Parent not detached");
            verify(!em.contains(existing), "Existing not removed");
            verify(em.contains(description), "Description not managed");
            removeFailed = false;
            immediateException = false;
            try {
                em.remove(parent);
                verify(!em.contains(parent), "Parent is managed");
                verify(!em.contains(description), "Description is still managed");
            } catch (IllegalArgumentException e) {
                removeFailed = true;
                immediateException = true;
            }
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (!checkForPersistenceException(e)) {
                        throw e;
                    }
                    removeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(removeFailed, "remove succeeded on a detached instance");
            verifyExistenceInNodeTable(existing.getId());
            verifyExistenceInDescriptionTable(description.getId());
        } finally {
            closeEntityManager(em);
        }
    }

    /* If X is a removed entity, it is ignored by the remove operation. */
    @Test
    public void testSimpleCascadeRemoved() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // one-to-many relationship
            CascadingNode parent = new CascadingNode(301, null);
            CascadingNode child = new CascadingNode(302, null);
            env.beginTransaction(em);
            em.persist(parent);
            em.persist(child);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            parent = em.find(CascadingNode.class, parent.getId());
            em.remove(parent);
            child = em.find(CascadingNode.class, child.getId());
            parent.addChild(child);
            verify(!em.contains(parent), "Parent not removed");
            verify(em.contains(child), "Child not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyExistenceInNodeTable(child.getId());
            // one-to-one relationship
            parent = new CascadingNode(303, null);
            CascadingNodeDescription description = new CascadingNodeDescription(304, null, "description");
            env.beginTransaction(em);
            em.persist(parent);
            em.persist(description);
            env.commitTransactionAndClear(em);
            env.beginTransaction(em);
            parent = em.find(CascadingNode.class, parent.getId());
            em.remove(parent);
            description = em.find(CascadingNodeDescription.class, description.getId());
            parent.setDescription(description);
            verify(!em.contains(parent), "Parent not removed");
            verify(em.contains(description), "Description not managed");
            em.remove(parent);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(parent.getId());
            verifyExistenceInDescriptionTable(description.getId());
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @ToBeInvestigated
    public void testCircularCascade() throws SQLException {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            CascadingNode node1 = new CascadingNode(401, null);
            CascadingNode node2 = new CascadingNode(402, node1);
            node2.addChild(node1);
            node1.setParent(node2);
            env.beginTransaction(em);
            em.persist(node1);
            env.commitTransactionAndClear(em);
            verifyExistenceInNodeTable(node1.getId());
            verifyExistenceInNodeTable(node2.getId());
            env.beginTransaction(em);
            node1 = em.find(CascadingNode.class, node1.getId());
            node2 = em.find(CascadingNode.class, node2.getId());
            em.remove(node1);
            env.commitTransactionAndClear(em);
            verifyAbsenceFromNodeTable(node1.getId());
            verifyAbsenceFromNodeTable(node2.getId());
        } finally {
            closeEntityManager(em);
        }
    }

    private void verifyExistenceInNodeTable(int nodeId) throws SQLException {
        verify(checkForExistenceInNodeTable(nodeId), "no node with id " + nodeId + " found using JDBC.");
    }

    private void verifyAbsenceFromNodeTable(int nodeId) throws SQLException {
        verify(!checkForExistenceInNodeTable(nodeId), "node with id " + nodeId + " still found using JDBC.");
    }

    private boolean checkForExistenceInNodeTable(int nodeId) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("select ID, PARENT from TMP_CASC_NODE where ID = ?");
            try {
                stmt.setInt(1, nodeId);
                ResultSet rs = stmt.executeQuery();
                try {
                    return rs.next();
                } finally {
                    rs.close();
                }
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }

    private void verifyExistenceInDescriptionTable(int descId) throws SQLException {
        verify(checkForExistenceInDescriptionTable(descId), "no description with id " + descId + " found using JDBC.");
    }

    private void verifyAbsenceFromDescriptionTable(int descId) throws SQLException {
        verify(!checkForExistenceInDescriptionTable(descId), "description with id " + descId + " still found using JDBC.");
    }

    private boolean checkForExistenceInDescriptionTable(int descId) throws SQLException {
        Connection conn = getEnvironment().getDataSource().getConnection();
        try {
            PreparedStatement stmt = conn.prepareStatement("select ID, DESC_TEXT from TMP_CASC_NODE_DESC where ID = ?");
            try {
                stmt.setInt(1, descId);
                ResultSet rs = stmt.executeQuery();
                try {
                    return rs.next();
                } finally {
                    rs.close();
                }
            } finally {
                stmt.close();
            }
        } finally {
            conn.close();
        }
    }
}
