/*
 * Copyright (c) 1998, 2021 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.unitofwork;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.framework.TestWarningException;
import org.eclipse.persistence.testing.models.employee.domain.Employee;


/**
 * <P><B>Purpose</B>:     To make sure that reading an object containing a bidirectional
 *                        relationship with a value holder does not cause an infinite loop when
 *                        using NoIdentityMap.
 *
 * <P><B>Motivation</B>:     This test was written to fix a bug.  When using NoIdentityMap, if an
 *                            Employee (which has a bidirectional relationship with a ValueHolder
 *                            managedEmployees) is read, it checks to see if a managedEmployee is in
 *                            the cache, and since there is no cache, reads the managedEmployee.  When
 *                            the managedEmployee is read, it too checks to see if its manager is in the
 *                            cache, and since there is none, reads its manager, hence causing an
 *                            infinite loop.
 *
 * <P><B>Design</B>:     First, the Employee descriptor is changed to use NoIdentityMap.  Next, a
 *                        Unit Of Work is acquired, and an attempt is made to read and change an Employee.
 *                        After the Employee is read, the Employee descriptor is reset to its original state.
 *
 * <P><B>Responsibilities</B>:     Verify that the above conditions do not cause an infinite loop.
 *
 * <P><B>Features Used</B>:     Unit Of Work, (No) Identity Map
 *
 * <P><B>Paths Covered</B>:     Attempting to read a org.eclipse.persistence.testing.models.employee.domain.Employee covers:
 *        <UL>
 *            <LI><CODE>manager</CODE> 1:1 Mapping
 *            <LI><CODE>managedEmployees</CODE> 1:M Mapping
 *        </UL>
 */
public class NoIMWithValueHolderTest extends AutoVerifyTestCase {
    public UnitOfWork unitOfWork;
    public ClassDescriptor originalEmployeeDescriptor;
    public OptimisticLockingPolicy policy;

    public NoIMWithValueHolderTest() {
        super();
        setDescription("This test case should NOT get into an infinite loop (if you're reading this, it passed).");
    }

    @Override
    public void reset() {
        if (getSession() instanceof org.eclipse.persistence.sessions.remote.RemoteSession) {
            return;
        }
        getAbstractSession().rollbackTransaction();
        // Reset the original Employee descriptor
        originalEmployeeDescriptor = getSession().getClassDescriptor(Employee.class);
        originalEmployeeDescriptor.useFullIdentityMap();
        originalEmployeeDescriptor.setOptimisticLockingPolicy(this.policy);
        originalEmployeeDescriptor.getQueryManager().checkCacheForDoesExist();
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
    }

    @Override
    public void setup() {
        if (getSession() instanceof org.eclipse.persistence.sessions.remote.RemoteSession) {
            throw new TestWarningException("This test cannot be run through the remote.");
        }
        getAbstractSession().beginTransaction();
        // Save the original Employee descriptor
        originalEmployeeDescriptor = getSession().getClassDescriptor(Employee.class);
        originalEmployeeDescriptor.useNoIdentityMap();
        this.policy = originalEmployeeDescriptor.getOptimisticLockingPolicy();
        originalEmployeeDescriptor.setOptimisticLockingPolicy(null);
        originalEmployeeDescriptor.getQueryManager().assumeExistenceForDoesExist();
    }

    @Override
    protected void test() {
        // Attempt to read and change an Employee
        unitOfWork = getSession().acquireUnitOfWork();
        Employee employee = (Employee)unitOfWork.readObject(Employee.class);
        employee.setFirstName("Yahoo");
        employee.setLastName("Serious");
        employee.setMale();
        unitOfWork.commit();
    }
}
