/*
 * Copyright (c) 2011, 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:
//     tware - test for bug 262157
package org.eclipse.persistence.testing.tests.simultaneous;

import java.math.BigDecimal;

import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.tests.unitofwork.ConcurrentLargeProject;
import org.eclipse.persistence.testing.tests.unitofwork.ConcurrentPerson;

import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.sessions.UnitOfWork;
/**
 * Test for Bug 262157
 * This test tests to ensure no dealock occurs in the following scenario
 * There is a bidirectional realtionship between an object (A) without inheritance and an object (B) with inheritance with a superclass (C)
 * A eagerly maps to C and B eagerly maps to A
 * If the mappings are setup so that A1 maps to B1 and B1 maps to A1, ensure no deadlock will occur
 * This test starts a thread that reads the A and pauses the build after it has acquired its locks.  It then starts
 * a thread that reads B and tests to ensure both threads run to completion
 * @author tware
 *
 */
public class ConcurrentReadOneToOneInheritanceTest extends AutoVerifyTestCase{

    protected BigDecimal personId = null;
    protected BigDecimal projectId = null;
    protected ConcurrentPerson person = null;

    protected boolean deadlockDetected = false;

    @Override
    public void setup(){
        deadlockDetected = false;
        UnitOfWork uow = getSession().acquireUnitOfWork();
        person = new ConcurrentPerson();
        person.name = "Wenger";
        ConcurrentLargeProject project = new ConcurrentLargeProject();
        project.setName("Football");
        person.setHobby(project);
        project.setSupervisor(person);
        uow.registerObject(person);
        uow.registerObject(project);
        uow.commit();
        uow.release();
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
        personId = person.id;
        projectId = project.getId();
    }

    @Override
    public void test(){
        ConcurrentPerson.RUNNING_TEST = ConcurrentPerson.ONE_TO_ONE_INHERITANCE;
        Thread thread1 = new Thread(new PersonReader(getSession().acquireUnitOfWork(), personId));
        Thread thread2 = new Thread(new LargeProjectReader(getSession().acquireUnitOfWork(), projectId));
        thread1.start();
        thread2.start();
        try {
            thread1.join(30000);
            if (thread1.isAlive()){
                try{
                    thread1.interrupt();
                    thread2.interrupt();
                }catch (Exception e) {
                }
                deadlockDetected = true;
            }
        } catch (InterruptedException ex) {

        }
    }

    @Override
    public void verify(){
        if (deadlockDetected){
            throw new TestErrorException("Deadlock detected when reading a bidirectional 1-1 with Inheritance.");
        }
    }

    @Override
    public void reset(){
        ConcurrentPerson.RUNNING_TEST = ConcurrentPerson.NONE;
        UnitOfWork uow = getSession().acquireUnitOfWork();
        uow.deleteObject(person.getHobby());
        uow.deleteObject(person);
        uow.commit();
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
    }

    public class PersonReader implements Runnable{
        private UnitOfWork uow;
        private BigDecimal id;

        public PersonReader(UnitOfWork uow, BigDecimal id){
            this.uow = uow;
            this.id = id;
        }

        @Override
        public void run(){
            uow.readObject(ConcurrentPerson.class, (new ExpressionBuilder()).get("id").equal(id));
        }
    }

    public class LargeProjectReader implements Runnable{
        private UnitOfWork uow;
        private BigDecimal id;

        public LargeProjectReader(UnitOfWork uow, BigDecimal id){
            this.uow = uow;
            this.id = id;
        }

        @Override
        public void run(){
            uow.readObject(ConcurrentLargeProject.class, (new ExpressionBuilder()).get("id").equal(id));
        }
    }
}
