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

import java.util.*;

import org.eclipse.persistence.descriptors.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.queries.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.exceptions.*;

import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.testing.framework.*;

/**
 * Tests fine-grained / descriptor level pessimistic locking in an
 * inheritance hierarchy.
 * <p>
 * Query on a large project, where the team leader attribute is joined, and
 * project alone is configured on the descriptor for pessimistic locking.
 * A subsequent attempt to read the project should fail, but not to lock the
 * employee.
 */
public class PessimisticLockInheritanceTest extends TestCase {
    public UnitOfWork uow;
    public short lockMode;
    CMPPolicy oldCMPPolicy;

    /**
     * PessimisticLockInheritanceTest constructor comment.
     */
    public PessimisticLockInheritanceTest(short lockMode) {
        this.lockMode = lockMode;
        setName(getName() + "(mode=" + lockMode + ")");
        setDescription("This test verifies the pessimistic locking feature works properly when set on the descriptor and inheritance is involved.");
    }

    @Override
    protected void setup() {
        getSession().getIdentityMapAccessor().initializeIdentityMaps();
        ClassDescriptor projectDescriptor = getSession().getDescriptor(org.eclipse.persistence.testing.models.employee.domain.Project.class);
        ClassDescriptor largeProjectDescriptor = getSession().getDescriptor(LargeProject.class);
        ClassDescriptor smallProjectDescriptor = getSession().getDescriptor(SmallProject.class);

        CMPPolicy cmpPolicy = new CMPPolicy();
        PessimisticLockingPolicy policy = new PessimisticLockingPolicy();
        policy.setLockingMode(this.lockMode);

        cmpPolicy.setPessimisticLockingPolicy(policy);
        oldCMPPolicy = projectDescriptor.getCMPPolicy();
        projectDescriptor.setCMPPolicy(cmpPolicy);
        projectDescriptor.getQueryManager().getReadObjectQuery().setLockMode(ObjectLevelReadQuery.DEFAULT_LOCK_MODE);
        ((ObjectLevelReadQuery)((ForeignReferenceMapping)projectDescriptor.getMappingForAttributeName("teamLeader")).getSelectionQuery()).setLockMode(ObjectLevelReadQuery.DEFAULT_LOCK_MODE);
        ClassDescriptor employeeDescriptor = getSession().getDescriptor(Employee.class);
        ((ObjectLevelReadQuery)((ForeignReferenceMapping)employeeDescriptor.getMappingForAttributeName("projects")).getSelectionQuery()).setLockMode(ObjectLevelReadQuery.DEFAULT_LOCK_MODE);
        largeProjectDescriptor.setCMPPolicy(cmpPolicy);
        largeProjectDescriptor.getQueryManager().getReadObjectQuery().setLockMode(ObjectLevelReadQuery.DEFAULT_LOCK_MODE);
        smallProjectDescriptor.setCMPPolicy(cmpPolicy);
        smallProjectDescriptor.getQueryManager().getReadObjectQuery().setLockMode(ObjectLevelReadQuery.DEFAULT_LOCK_MODE);
    }

    @Override
    public void reset() {
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
        if (uow != null) {
            uow.release();
        }
        ClassDescriptor projectDescriptor = getSession().getDescriptor(org.eclipse.persistence.testing.models.employee.domain.Project.class);
        ClassDescriptor largeProjectDescriptor = getSession().getDescriptor(LargeProject.class);
        ClassDescriptor smallProjectDescriptor = getSession().getDescriptor(SmallProject.class);
        projectDescriptor.setCMPPolicy(oldCMPPolicy);
        ((ObjectLevelReadQuery)((ForeignReferenceMapping)projectDescriptor.getMappingForAttributeName("teamLeader")).getSelectionQuery()).setLockMode(ObjectLevelReadQuery.DEFAULT_LOCK_MODE);
        ((ObjectLevelReadQuery)((ForeignReferenceMapping)projectDescriptor.getMappingForAttributeName("teamLeader")).getSelectionQuery()).dontRefreshIdentityMapResult();
        ClassDescriptor employeeDescriptor = getSession().getDescriptor(Employee.class);
        ((ObjectLevelReadQuery)((ForeignReferenceMapping)employeeDescriptor.getMappingForAttributeName("projects")).getSelectionQuery()).setLockMode(ObjectLevelReadQuery.DEFAULT_LOCK_MODE);
        ((ObjectLevelReadQuery)((ForeignReferenceMapping)employeeDescriptor.getMappingForAttributeName("projects")).getSelectionQuery()).dontRefreshIdentityMapResult();
        largeProjectDescriptor.setCMPPolicy(oldCMPPolicy);
        smallProjectDescriptor.setCMPPolicy(oldCMPPolicy);
    }

    @Override
    public void test() throws Exception {
        checkSelectForUpateSupported();

        if (this.lockMode == ObjectLevelReadQuery.LOCK_NOWAIT) {
            checkNoWaitSupported();
        }

        uow = getSession().acquireUnitOfWork();

        ReadObjectQuery query = new ReadObjectQuery(LargeProject.class);

        // Only Charles Chanley and John Way are team leaders of projects they are also working on.
        Expression expression = query.getExpressionBuilder().get("teamLeader").get("firstName").equal("Charles");
        query.setSelectionCriteria(expression);
        query.addJoinedAttribute("teamLeader");

        Object result = uow.executeQuery(query);

        // Now trigger the valueholder...
        ((LargeProject)result).getTeamLeader();

        ReadObjectQuery cacheQuery = new ReadObjectQuery(org.eclipse.persistence.testing.models.employee.domain.Project.class);
        cacheQuery.checkCacheOnly();
        Object cachedObject = uow.executeQuery(cacheQuery);
        if (result != cachedObject) {
            throw new TestErrorException("Did not get a cache hit when using pessimistic locking.");
        }
        cacheQuery = new ReadObjectQuery(Employee.class);
        cacheQuery.checkCacheOnly();
        cachedObject = uow.executeQuery(cacheQuery);
        if (((LargeProject)result).getTeamLeader() != cachedObject) {
            throw new TestErrorException("Did not get a cache hit after pessimisticly locking a joined attribute.");
        }
        Vector projects = ((Employee)cachedObject).getProjects();

        // Test the lock.
        DatabaseSession session2 = null;
        UnitOfWork uow2 = null;
        try {
            if (getSession() instanceof org.eclipse.persistence.sessions.remote.RemoteSession) {
                session2 = org.eclipse.persistence.testing.tests.remote.RemoteModel.getServerSession().getProject().createDatabaseSession();
            } else {
                session2 = getSession().getProject().createDatabaseSession();
            }
            session2.setLog(getSession().getLog());
            session2.setLogLevel(getSession().getLogLevel());
            session2.login();
            uow2 = session2.acquireUnitOfWork();
            boolean isLocked = false;
            query = new ReadObjectQuery(Employee.class);
            expression = query.getExpressionBuilder().get("firstName").equal("Charles");
            query.setSelectionCriteria(expression);
            Employee result2 = (Employee)uow2.executeQuery(query);
            if (result2 == null) {
                throw new TestErrorException("A joined attribute was mistakenly locked pessimistically.");
            }
            projects = null;
            try {
                projects = result2.getProjects();
            } catch (EclipseLinkException exeception) {
                session2.logMessage(exeception.toString());
                isLocked = true;
            }
            if (projects == null) {
                isLocked = true;
            }
            if (!isLocked) {
                throw new TestErrorException("Select for update does not acquire a lock");
            }
        } catch (RuntimeException e) {
            throw e;
        } finally {
            if (uow2 != null) {
                uow2.release();
            }
            if (session2 != null) {
                session2.logout();
            }
        }
    }
}
