/*
 * 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 java.math.BigDecimal;

import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.framework.TestWarningException;


public class ConcurrentReadOnUpdateWithEarlyTransTest extends TestCase {
    // used as monitor for test
    public static ConcurrentAddress readAddress;
    public ConcurrentAddress originalReference;
    public ConcurrentAddress readObject;

    //used in remote unit of work tests to control when the lock is released
    public static int whosWaiting;
    public static final int READER = 2;
    public static final int WRITER = 1;
    public static ThreadLocal threadId = new ThreadLocal();

    public ConcurrentReadOnUpdateWithEarlyTransTest() {
    }

    @Override
    public void setup() {
        // The purpose of this test is to test multi-threaded server execution,
        // remote is for a single client, so this test is not relevant.
        if (getSession().isDistributedSession()) {
            throw new TestWarningException("Test unavailable on Remote UnitOfWork.");
        }
        readAddress = new ConcurrentAddress();
        readAddress.setId(new BigDecimal(8));
        readAddress.setCity("Toronto");
        readAddress.setPostalCode("L5J2B5");
        readAddress.setProvince("ONT");
        readAddress.setStreet("1450 Acme Cr., suite 4");
        readAddress.setCountry("Canada");
        UnitOfWork uow = getSession().acquireUnitOfWork();
        uow.registerObject(readAddress);
        uow.commit();
        ConcurrentAddress.RUNNING_TEST = ConcurrentAddress.READ_ON_UPDATE_EARLY_TRANS;
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
    }

    @Override
    public void test() {
        UnitOfWork uow = getSession().acquireUnitOfWork();
        ConcurrentPerson person = (ConcurrentPerson)uow.readObject(ConcurrentPerson.class);
        originalReference = person.getAddress();
        uow.beginEarlyTransaction();
        ConcurrentAddress addressClone =
            (ConcurrentAddress)uow.readObject(ConcurrentReadOnUpdateWithEarlyTransTest.readAddress);
        person.setAddress(addressClone);
        //begin multi threading
        Thread loadThread = new Thread(this.runnable());
        loadThread.start();
        threadId.set("Writer");
        try {
            //let the reader start
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        }
        uow.commit();
        try {
            loadThread.join();
        } catch (InterruptedException ex) {
        }
    }

    public Runnable runnable() {
        return new Runnable() {
                @Override
                public void run() {
                    threadId.set("Reader");
                    synchronized (ConcurrentReadOnUpdateWithEarlyTransTest.readAddress) {
                        ConcurrentReadOnUpdateWithEarlyTransTest.whosWaiting =
                                ConcurrentReadOnUpdateWithEarlyTransTest.READER;
                        try {
                            ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.wait(30000);
                        } catch (InterruptedException ex) {
                        }
                    }
                    readObject =
                            (ConcurrentAddress)getSession().readObject(ConcurrentReadOnUpdateWithEarlyTransTest.readAddress);
                    synchronized (ConcurrentReadOnUpdateWithEarlyTransTest.readAddress) {
                        ConcurrentReadOnUpdateWithEarlyTransTest.readAddress.notifyAll(); //wake writer
                    }
                }
            };
    }

    @Override
    public void verify() {
        ConcurrentPerson person = (ConcurrentPerson)getSession().readObject(ConcurrentPerson.class);
        if (person.getAddress() != readObject) {
            throw new TestErrorException("Object Identity Lost during merge");
        }
    }

    @Override
    public void reset() {
        ConcurrentAddress.RUNNING_TEST = ConcurrentAddress.NONE;
        try {
            UnitOfWork unitOfWork = getSession().acquireUnitOfWork();
            ((ConcurrentPerson)unitOfWork.readObject(ConcurrentPerson.class)).setAddress((ConcurrentAddress)unitOfWork.registerObject(originalReference));
            unitOfWork.deleteObject(ConcurrentReadOnUpdateWithEarlyTransTest.readAddress);
            unitOfWork.commit();
        } finally {
            ConcurrentReadOnInsertTest.readAddress = null;
        }
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
    }
}
