/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.simultaneous;


import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.models.employee.domain.Employee;
import org.eclipse.persistence.testing.models.employee.domain.Project;
import org.eclipse.persistence.testing.models.employee.domain.SmallProject;

import org.eclipse.persistence.testing.models.employee.domain.Address;

//see bug 305611

public class AppendLockTest extends AutoVerifyTestCase {

    Employee emp = null;
    SmallProject project = null;
    Address address = null;

    public AppendLockTest() {
        super();
    }


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

    @Override
    protected void test() throws Throwable {
        // TODO Auto-generated method stub
        super.test();
        Thread locker = new Thread(new Locker(getSession(), address));
        Thread writer1 = new Thread(new Writer1(getSession(), emp, project, address));
        Thread writer2 = new Thread (new Writer2(getSession(), project));
        locker.start();
        writer1.start();
        writer2.start();
        writer2.join(60000);
        try{
        if (writer2.isAlive()){
            try{
            writer2.interrupt();
            writer1.interrupt();
            locker.interrupt();
            }catch (Exception e) {
            }
            fail("Bug 9484687 - deadlock occured.");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
          }

    @Override
    public void reset() throws Throwable {
        super.reset();
        getExecutor().resetSession();
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
        UnitOfWork uow = getSession().acquireUnitOfWork();
        this.project = (SmallProject) uow.refreshObject(project);
        this.emp = (Employee)uow.refreshObject(emp);
        uow.deleteObject(project);
        uow.deleteObject(emp);
        uow.commit();
    }

    public static class Writer1 implements Runnable{
        protected Project project;
        protected Employee emp;
        protected Session session;
        protected Address address;

        public Writer1(Session session, Employee emp, Project project, Address address){
            this.session = session;
            this.project = project;
            this.emp = emp;
            this.address =address;
        }

        @Override
        public void run() {
            UnitOfWork uow = session.acquireUnitOfWork();
            Project p = (Project) uow.readObject(project);
            Address address = (Address) uow.readObject(this.address);
            Employee emp = (Employee) uow.readObject(this.emp);
            emp.setAddress(address);
            p.setDescription("SomeBigLongDescription");
            ((AbstractSession)this.session).getIdentityMapAccessorInstance().getCacheKeyForObject(this.project).setObject(null);
            ((UnitOfWorkImpl)uow).getCloneToOriginals().remove(p);
            synchronized (this.session) {
                try {
                    this.session.notifyAll();
                    this.session.wait(20000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            uow.commit();
            synchronized (this.session) {
                    this.session.notifyAll();
            }
        }

    }

    public static class Locker implements Runnable{
        protected Address address;
        protected Session session;

        public Locker(Session session, Address address){
            this.session = session;
            this.address = address;
        }

        @Override
        public void run() {
            CacheKey cacheKey = null;
            synchronized (this.session) {
                try {
                    this.session.wait(20000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            try{
                 cacheKey = ((AbstractSession)this.session).getIdentityMapAccessorInstance().acquireLock(this.address.getId(), this.address.getClass(), this.session.getClassDescriptor(this.address), false);
                synchronized (this.session) {
                    this.session.notifyAll();
                    try {
                        this.session.wait(5000);
                    } catch (InterruptedException e) {
                        //TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }finally{
                cacheKey.release();
            }
        }

    }

    public static class Writer2 implements Runnable{
        protected Session session;
        protected Project project;


        public Writer2(Session session, Project project){
            this.session = session;
            this.project = project;
        }

        @Override
        public void run() {
            synchronized (this.session) {
                try {
                    this.session.wait(20000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (this.session) {
                try {
                    this.session.wait(20000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (this.session) {
                try {
                    this.session.wait(20000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            UnitOfWork uow = this.session.acquireUnitOfWork();
            try{
            this.project = (Project) uow.refreshObject(this.project); // should block

                synchronized (this.session) {
                        this.session.notifyAll();
                }
                uow.release();
            }catch(Exception ex){
                System.out.println("Thread was interrupted");
            }
        }

    }

}
