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

import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.models.employee.domain.Employee;

import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.models.employee.domain.SmallProject;

public class ConcurrencyTest extends AutoVerifyTestCase {

    Employee emp = null;
    SmallProject project = null;


    public ConcurrencyTest() {
        super();
    }


    @Override
    protected void setup() throws Throwable {
        super.setup();
        UnitOfWork uow = getSession().acquireUnitOfWork();
        project = new SmallProject();
        uow.registerNewObject(project);
        emp = new Employee();
        uow.registerNewObject(emp);
        uow.commit();
    }

    @Override
    protected void test() throws Throwable {
        // TODO Auto-generated method stub
        super.test();
            Integer i = Integer.valueOf(5);
            Thread thread1 = new Thread(new Runner1(i,  emp.getId(),project.getId(),getSession()));
            thread1.setName("Runner1");
            Thread thread2 = new Thread(new Runner2(i, emp.getId(),project.getId(),getSession()));
            thread2.setName("Runner2");
            thread2.start();
            thread1.start();
            try {
                Thread.sleep(8000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized (i) {
                i.notifyAll();
            }
            try {
                thread2.join(30000);
                thread1.join(30000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            if (thread2.isAlive() || thread1.isAlive()){
                thread2.interrupt();
                thread1.interrupt();
                fail("Dead-lock occurred");
           }

    }

    @Override
    public void reset() throws Throwable {
        super.reset();
        UnitOfWork uow = getSession().acquireUnitOfWork();
        this.emp = (Employee)uow.readObject(emp);
        this.emp.getProjects().clear();
        uow.deleteObject(uow.readObject(project));
        uow.deleteObject(emp);
        uow.commit();
    }
}
