/*
 * Copyright (c) 1998, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import jakarta.persistence.EntityManager;

import junit.framework.*;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.BranchA;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.BranchB;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.CascadeDeleteTableCreator;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.LeafA;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.LeafB;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.MachineState;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.PersistentIdentity;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.RootA;
import org.eclipse.persistence.testing.models.jpa.cascadedeletes.ThreadInfo;

public class CascadeDeletesJUnitTestSuite extends JUnitTestCase {

    public CascadeDeletesJUnitTestSuite() {
        super();
    }

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

    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.setName("CascadeDeletesJUnitTestSuite");
        suite.addTest(new CascadeDeletesJUnitTestSuite("testSetup"));
        suite.addTest(new CascadeDeletesJUnitTestSuite("testDeleteWholeTree"));
        suite.addTest(new CascadeDeletesJUnitTestSuite("testRemoveMachineState"));
        suite.addTest(new CascadeDeletesJUnitTestSuite("testDeletePrivateOwned"));
        suite.addTest(new CascadeDeletesJUnitTestSuite("testDeleteBranchBTree"));
        suite.addTest(new CascadeDeletesJUnitTestSuite("testDeletePrivateOwnedChild"));
        return suite;
    }

    /**
     * The setup is done as a test, both to record its failure, and to allow
     * execution in the server.
     */
    public void testSetup() {
        new CascadeDeleteTableCreator().replaceTables(JUnitTestCase.getServerSession("cascade-deletes"));
        clearCache("cascade-deletes");
    }

    public void testRemoveMachineState(){
        EntityManager em = createEntityManager("cascade-deletes");
        beginTransaction(em);

        MachineState ms = new MachineState();
        ms.setId(1);
        ms.setThreads(new ArrayList<ThreadInfo>());
        ms.getThreads().add(new ThreadInfo(1, "main"));

        em.persist(ms);

        commitTransaction(em);

        beginTransaction(em);

        ms = em.find(MachineState.class, 1L);

        em.remove(ms);

        commitTransaction(em);

    }

    public void testDeleteWholeTree() {
        Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>();
        RootA rootA = createTree(allEntities);

        EntityManager em = createEntityManager("cascade-deletes");
        try {
            beginTransaction(em);
            rootA = em.find(RootA.class, rootA.getId());
            // :(
            for (BranchA a : rootA.getBranchAs()) {
                a.getLeafs().size();
            }
            em.remove(rootA);
            for (PersistentIdentity entity : allEntities) {
                assertNull("Contains found removed entity", em.find(entity.getClass(), entity.getId()));
            }
            commitTransaction(em);
            closeEntityManager(em);
            clearCache("cascade-deletes");

            em = createEntityManager("cascade-deletes");
            for (PersistentIdentity entity : allEntities) {
                assertNull("Failed to remove all entities, found entity class: " +  entity.getClass() + " with Id: " + entity.getId(), em.find(entity.getClass(), entity.getId()));
            }
            closeEntityManager(em);

        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }finally{
            deleteTree();
        }
    }

    public void testDeletePrivateOwned() {
        Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>();
        RootA rootA = createTree(allEntities);

        EntityManager em = createEntityManager("cascade-deletes");
        try {
            beginTransaction(em);
            BranchB branchB = (BranchB) em.createQuery("Select b from BranchB b join b.branchBs bb where bb.leafBs is not empty").getResultList().get(0);
            BranchB subB = branchB.getBranchBs().get(0);
            subB.getLeafBs().size();
            branchB.getBranchBs().clear();
            commitTransaction(em);
            closeEntityManager(em);
            clearCache("cascade-deletes");
            em = createEntityManager("cascade-deletes");
            assertNull("private owned object was not deleted.", em.find(BranchB.class, subB.getId()));
            assertNotNull("child of PO object was deleted in error", em.find(LeafB.class, subB.getLeafBs().get(0).getId()));



        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }finally{
            deleteTree();
        }
    }

    public void testDeletePrivateOwnedChild() {
        Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>();
        createTree(allEntities);

        EntityManager em = createEntityManager("cascade-deletes");
        try {
            beginTransaction(em);
            RootA rootA = (RootA) em.createQuery("Select r from RootA r join r.branchAs ba where ba.secondSet is not empty").getResultList().get(0);
            BranchA subA = rootA.getBranchAs().get(0);
            subA.getLeafs().size();
            rootA.getBranchAs().remove(subA);

            commitTransaction(em);
            closeEntityManager(em);
            clearCache("cascade-deletes");
            em = createEntityManager("cascade-deletes");
            assertNull("private owned object was not deleted.", em.find(BranchA.class, subA.getId()));
            for (LeafA leafA : subA.getLeafs()){
                assertNull("child of PO object was deleted in error", em.find(LeafA.class, leafA.getId()));
            }


        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }finally{
            deleteTree();
        }
    }

    public void testDeleteBranchBTree() {
        Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>();
        RootA rootA = createTree(allEntities);

        EntityManager em = createEntityManager("cascade-deletes");
        try {
            beginTransaction(em);
            rootA = em.find(RootA.class, rootA.getId());
            BranchB removed = rootA.getBranchB();
            em.remove(removed);
            rootA.setBranchB(null);
            assertFalse("Failed to remove all entities in tree", removed.checkTreeForRemoval(em));
            commitTransaction(em);
            closeEntityManager(em);
            clearCache("cascade-deletes");

            em = createEntityManager("cascade-deletes");
            assertFalse("Failed to remove all entities in tree", removed.checkTreeForRemoval(em));
            closeEntityManager(em);

        } catch (RuntimeException ex) {
            if (isTransactionActive(em)) {
                rollbackTransaction(em);
            }
            closeEntityManager(em);
            throw ex;
        }finally{
            deleteTree();
        }
    }

    public RootA createTree(Collection<PersistentIdentity> allEntities) {
        EntityManager em = createEntityManager("cascade-deletes");
        beginTransaction(em);
        RootA rootA = new RootA();
        em.persist(rootA);
        allEntities.add(rootA);
        BranchA branchA = new BranchA();
        em.persist(branchA);
        allEntities.add(branchA);
        BranchA subBranch = new BranchA();
        em.persist(subBranch);
        allEntities.add(subBranch);
        branchA.setBranchA(subBranch);
        LeafA leafA = new LeafA();
        em.persist(leafA);
        allEntities.add(leafA);
        leafA.setBranchA(branchA);
        branchA.getLeafs().add(leafA);

        leafA = new LeafA();
        em.persist(leafA);
        allEntities.add(leafA);
        branchA.getSecondSet().add(leafA);
        leafA = new LeafA();
        em.persist(leafA);
        allEntities.add(leafA);
        branchA.getSecondSet().add(leafA);



        leafA = new LeafA();
        em.persist(leafA);
        allEntities.add(leafA);
        leafA.setBranchA(branchA);
        branchA.getLeafs().add(leafA);
        rootA.getBranchAs().add(branchA);
        branchA = new BranchA();
        em.persist(branchA);
        allEntities.add(branchA);
        subBranch = new BranchA();
        em.persist(subBranch);
        allEntities.add(subBranch);
        branchA.setBranchA(subBranch);
        leafA = new LeafA();
        em.persist(leafA);
        allEntities.add(leafA);
        leafA.setBranchA(branchA);
        branchA.getLeafs().add(leafA);
        leafA = new LeafA();
        em.persist(leafA);
        allEntities.add(leafA);
        leafA.setBranchA(branchA);
        branchA.getLeafs().add(leafA);
        rootA.getBranchAs().add(branchA);

        BranchB branchB = new BranchB();
        em.persist(branchB);
        allEntities.add(branchB);
        rootA.setBranchB(branchB);

        BranchB subbranchB = new BranchB();
        em.persist(subbranchB);
        allEntities.add(subbranchB);
        LeafB subbranchBLeafB = new LeafB();
        em.persist(subbranchBLeafB);
        subbranchB.getLeafBs().add(subbranchBLeafB);

        branchB.getBranchBs().add(subbranchB);
        subbranchB = new BranchB();
        em.persist(subbranchB);
        allEntities.add(subbranchB);
        branchB.getBranchBs().add(subbranchB);

        LeafB leafB = new LeafB();
        em.persist(leafB);
        allEntities.add(leafB);
        branchB.getLeafBs().add(leafB);
        leafB = new LeafB();
        em.persist(leafB);
        allEntities.add(leafB);
        branchB.getLeafBs().add(leafB);
        commitTransaction(em);
        closeEntityManager(em);
        clearCache("cascade-deletes");
        return rootA;
    }

    public void deleteTree() {
        EntityManager em = createEntityManager("cascade-deletes");
        beginTransaction(em);
        List<RootA> result = (List<RootA>)em.createQuery("Select r from RootA r").getResultList();
        for (RootA root : result){
            root.getBranchAs().clear();
            root.setBranchB(null);
        }
        List<BranchA> result2 = (List<BranchA>)em.createQuery("Select r from BranchA r").getResultList();
        for (BranchA root : result2){
            root.getLeafs().clear();
            root.getSecondSet().clear();
            root.setBranchA(null);
        }
        List<BranchB> result3 = (List<BranchB>)em.createQuery("Select r from BranchB r").getResultList();
        for (BranchB root : result3){
            root.getBranchBs().clear();
            root.getLeafBs().clear();
        }
        List<LeafA> result4 = (List<LeafA>)em.createQuery("Select r from LeafA r").getResultList();
        for (LeafA root : result4){
            root.setBranchA(null);
        }
        em.flush();
        em.createQuery("delete from RootA").executeUpdate();
        em.createQuery("delete from BranchA").executeUpdate();
        em.createQuery("delete from BranchB").executeUpdate();
        em.createQuery("delete from LeafA").executeUpdate();
        em.createQuery("delete from LeafB").executeUpdate();
        commitTransaction(em);
        closeEntityManager(em);
        clearCache("cascade-deletes");
    }

}
