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

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;

public class TestCascadeRefresh extends JPA1Base {

    @Test
    @ToBeInvestigated
    public void testCascade() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // on db: child -> grandchild
            // before refresh: parent (FOR_INSERT) -> child -> null
            // after refresh: parent -> child -> grandchild
            CascadingNode parent = new CascadingNode(1, null);
            CascadingNodeDescription parentDescription = new CascadingNodeDescription(2, null, "parent");
            parent.setDescription(parentDescription);
            CascadingNode child = new CascadingNode(3, null);
            CascadingNodeDescription childDescription = new CascadingNodeDescription(4, null, "child");
            child.setDescription(childDescription);
            CascadingNode grandchild = new CascadingNode(5, child);
            CascadingNodeDescription grandchildDescription = new CascadingNodeDescription(6, null, "grandchild");
            grandchild.setDescription(grandchildDescription);
            env.beginTransaction(em);
            em.persist(child);
            env.commitTransactionAndClear(em);
            verifyAbsence(em, parent);
            verifyAbsence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            verifyExistence(em, grandchild);
            verifyExistence(em, grandchildDescription);
            env.beginTransaction(em);
            em.persist(parent);
            verify(em.contains(parent), "parent is not managed");
            verify(em.contains(parentDescription), "parentDescription is not managed");
            child = em.find(CascadingNode.class, Integer.valueOf(child.getId()));
            childDescription = em.find(CascadingNodeDescription.class, Integer.valueOf(childDescription.getId()));
            childDescription.setDescription("updated");
            parent.addChild(child);
            child.setChildren(null);
            // setup complete
            em.refresh(parent);
            CascadingNode refreshedNode = parent;
            verify(em.contains(refreshedNode), "refreshed entity not managed");
            CascadingNodeDescription refreshedDescription = refreshedNode.getDescription();
            verify(refreshedDescription == parentDescription, "refreshed entity is a copy");
            verify(em.contains(refreshedDescription), "refreshed entity not managed");
            Set<CascadingNode> refreshedChildren = refreshedNode.getChildren();
            verify(refreshedChildren.size() == 1, "Wrong number of children: expected 1, got " + refreshedChildren.size());
            for (CascadingNode temp : refreshedChildren) {
                refreshedNode = temp;
                break;
            }
            verify(refreshedNode == child, "refreshed entity is a copy");
            verify(em.contains(refreshedNode), "refreshed entity not managed");
            refreshedDescription = refreshedNode.getDescription();
            verify(refreshedDescription == childDescription, "refreshed entity is a copy");
            verify(em.contains(refreshedDescription), "refreshed entity not managed");
            verify("child".equals(refreshedDescription.getDescription()), "refreshed entity has wrong description: "
                    + refreshedDescription.getDescription());
            refreshedChildren = refreshedNode.getChildren();
            verify(refreshedChildren.size() == 1, "Wrong number of children: expected 1, got " + refreshedChildren.size());
            for (CascadingNode temp : refreshedChildren) {
                refreshedNode = temp;
                break;
            }
            verify(refreshedNode.getId() == grandchild.getId(), "refreshed entity has wrong id: expected " + grandchild.getId()
                    + ", got " + refreshedNode.getId());
            verify(em.contains(refreshedNode), "refreshed entity not managed");
            refreshedDescription = refreshedNode.getDescription();
            verify(refreshedDescription.getId() == grandchildDescription.getId(), "refreshed entity has wrong id: expected "
                    + grandchildDescription.getId() + ", got " + refreshedDescription.getId());
            verify(em.contains(refreshedDescription), "refreshed entity not managed");
            refreshedChildren = refreshedNode.getChildren();
            verify(refreshedChildren == null || refreshedChildren.size() == 0, "Node has children, expected none");
            childDescription.setDescription("updated");
            env.commitTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            verifyDescription(em, childDescription, "updated");
        } finally {
            closeEntityManager(em);
        }
    }

    private void verifyExistence(EntityManager em, Object entity) {
        if (entity instanceof CascadingNode) {
            CascadingNode node = (CascadingNode) entity;
            CascadingNode found = em.find(CascadingNode.class, Integer.valueOf(node.getId()));
            verify(found != null, "cascading node with id " + node.getId() + " not found");
        } else if (entity instanceof CascadingNodeDescription) {
            CascadingNodeDescription desc = (CascadingNodeDescription) entity;
            CascadingNodeDescription found = em.find(CascadingNodeDescription.class, Integer.valueOf(desc.getId()));
            verify(found != null, "cascading node description with id " + desc.getId() + " not found");
        } else {
            throw new IllegalArgumentException("not supported");
        }
    }

    private void verifyAbsence(EntityManager em, Object entity) {
        if (entity instanceof CascadingNode) {
            CascadingNode node = (CascadingNode) entity;
            CascadingNode found = em.find(CascadingNode.class, Integer.valueOf(node.getId()));
            verify(found == null, "cascading node with id " + node.getId() + " found");
        } else if (entity instanceof CascadingNodeDescription) {
            CascadingNodeDescription desc = (CascadingNodeDescription) entity;
            CascadingNodeDescription found = em.find(CascadingNodeDescription.class, Integer.valueOf(desc.getId()));
            verify(found == null, "cascading node description with id " + desc.getId() + " found");
        } else {
            throw new IllegalArgumentException("not supported");
        }
    }

    private void verifyDescription(EntityManager em, CascadingNodeDescription desc, String expectedDescription) {
        CascadingNodeDescription found = em.find(CascadingNodeDescription.class, Integer.valueOf(desc.getId()));
        verify(found != null, "cascading node description with id " + desc.getId() + " not found");
        if (found != null) {
            verify(expectedDescription.equals(found.getDescription()), "cascading node " + found.getId()
                    + "has wrong description, excpected" + expectedDescription + " got " + found.getDescription());
        }
    }
}
