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

import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.expressions.*;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.forceupdate.*;

/**
    Scenario:
    Two threads(here we use two UOWs to simulate two threads) read in the same emplyee
    object. The first thread updates employee's address(relationship) and commits. The
    second thread updates the emplyee's salary(non-relationship attribute based on
    where the emplyee lives)and commits. No exception is thrown but the updated salary
    is invalid. If the first thread forces update the version value of the employee, an
    optimistic lock exception is thrown in the second thread.

    (Timestamp locking stores in the cache)
    Test 1: (Correctly use method forceUpdateToVersionField())
    UOW1 updates employee's address,
    calls forceUpdateToVersionField(Object cloneFromUOW1,true) and commits.
    UOW2 updates the employee's salary and commits.
    The test verified an optimistic lock exception is thrown in UOW2.

    Test 2: (forceUpdateToVersionField() doesn't effect read-only UOW)
    UOW1 updates employee's address,
    calls forceUpdateToVersionField(Object cloneFromUOW1,true) and commits.
    UOW2 has only read-operation and commits.
    The test verified no optimistic lock exception is thrown in UOW2.

    Test 3: (Test method removeForceUpdateToVersionField())
    UOW1 updates employee's address,
    calls forceUpdateToVersionField(cloneFromUOW1,true),COMMIT&amp;RESUMEs.
    It calls removeForceUpdateToVersionField(cloneFromUOW1),
    updates employee's address again and commits.
    UOW2 reads employee after the first commit of UOW1,updates the emplyee's salary
    and commits.
    The test verified no optimistic lock exception is thrown in UOW2.

    Test 4: (Demonstrate the result when no using forceUpdateToVersionField())
    UOW1 updates employee's address, commits.
    UOW2 updates the employee's salary and commits.
    The test verified no optimistic lock exception is thrown in UOW2.
*/
public class FUVLTimestampLockInCacheTest extends TransactionalTestCase {
    boolean exceptionCaught = false;
    int testnumber;

    public FUVLTimestampLockInCacheTest(int anInt) {
        testnumber = anInt;
        setName(getName() + "(Test" + anInt + ")");
        switch (testnumber) {
        case 1:
            setDescription("Correctly use method forceUpdateToVersionField()");
            break;
        case 2:
            setDescription("forceUpdateToVersionField() doesn't effect read-only UOW");
            break;
        case 3:
            setDescription("Test method removeForceUpdateToVersionField()");
            break;
        case 4:
            setDescription("Demonstrate the result when no using forceUpdateToVersionField()");
            break;
        default:
            break;
        }
    }

    @Override
    public void test() {
        switch (testnumber) {
        case 1:
            test1();
            break;
        case 2:
            test2();
            break;
        case 3:
            test3();
            break;
        case 4:
            test4();
            break;
        default:
            break;
        }
    }

    public void test1() {
        UnitOfWork uow1, uow2;

        ExpressionBuilder bldr = new ExpressionBuilder();
        Expression exp1 = bldr.get("firstName").equal("Bob");
        Expression exp2 = bldr.get("lastName").equal("Smith");
        Expression exp = exp1.and(exp2);

        EmployeeTLIC emp = (EmployeeTLIC)getSession().readObject(EmployeeTLIC.class, exp);

        uow1 = getSession().acquireUnitOfWork();
        uow2 = getSession().acquireUnitOfWork();
        EmployeeTLIC clone1 = (EmployeeTLIC)uow1.registerObject(emp);
        EmployeeTLIC clone2 = (EmployeeTLIC)uow2.registerObject(emp);

        uow1.forceUpdateToVersionField(clone1, true);
        clone1.getAddress().setStreet("4 Hutton Centre,Suite 900");
        clone1.getAddress().setCity("Santa Ana");
        clone1.getAddress().setProvince("CA");
        clone1.getAddress().setCountry("USA");
        clone1.getAddress().setPostalCode("92797");
        uow1.commit();

        clone2.setSalary(clone2.getSalary() + 200);
        try {
            uow2.commit();
        } catch (OptimisticLockException exception) {
            exceptionCaught = true;
        }
    }

    public void test2() {
        UnitOfWork uow1, uow2;

        ExpressionBuilder bldr = new ExpressionBuilder();
        Expression exp1 = bldr.get("firstName").equal("Bob");
        Expression exp2 = bldr.get("lastName").equal("Smith");
        Expression exp = exp1.and(exp2);

        EmployeeTLIC emp = (EmployeeTLIC)getSession().readObject(EmployeeTLIC.class, exp);

        uow1 = getSession().acquireUnitOfWork();
        uow2 = getSession().acquireUnitOfWork();
        EmployeeTLIC clone1 = (EmployeeTLIC)uow1.registerObject(emp);
        EmployeeTLIC clone2 = (EmployeeTLIC)uow2.registerObject(emp);

        uow1.forceUpdateToVersionField(clone1, true);
        clone1.getAddress().setStreet("4 Hutton Centre,Suite 900");
        clone1.getAddress().setCity("Santa Ana");
        clone1.getAddress().setProvince("CA");
        clone1.getAddress().setCountry("USA");
        clone1.getAddress().setPostalCode("92797");
        uow1.commit();

        // uow2 has only read-operation here
        //...
        try {
            uow2.commit();
        } catch (OptimisticLockException exception) {
            exceptionCaught = true;
        }
    }

    public void test3() {
        UnitOfWork uow1, uow2;

        ExpressionBuilder bldr = new ExpressionBuilder();
        Expression exp1 = bldr.get("firstName").equal("Bob");
        Expression exp2 = bldr.get("lastName").equal("Smith");
        Expression exp = exp1.and(exp2);

        EmployeeTLIC emp = (EmployeeTLIC)getSession().readObject(EmployeeTLIC.class, exp);

        uow1 = getSession().acquireUnitOfWork();
        EmployeeTLIC clone1 = (EmployeeTLIC)uow1.registerObject(emp);

        uow1.forceUpdateToVersionField(clone1, true);
        clone1.getAddress().setStreet("100 Young Street");
        clone1.getAddress().setCity("Toronto");
        clone1.getAddress().setProvince("ON");
        clone1.getAddress().setCountry("CANADA");
        clone1.getAddress().setPostalCode("K489Y7");
        uow1.commitAndResume();
        uow1.removeForceUpdateToVersionField(clone1);

        uow2 = getSession().acquireUnitOfWork();
        EmployeeTLIC clone2 = (EmployeeTLIC)uow2.registerObject(emp);

        clone1.getAddress().setStreet("4 Hutton Centre,Suite 900");
        clone1.getAddress().setCity("Santa Ana");
        clone1.getAddress().setProvince("CA");
        clone1.getAddress().setCountry("USA");
        clone1.getAddress().setPostalCode("92797");
        uow1.commit();

        clone2.setSalary(clone2.getSalary() + 200);
        try {
            uow2.commit();
        } catch (OptimisticLockException exception) {
            exceptionCaught = true;
        }
    }

    public void test4() {
        UnitOfWork uow1, uow2;

        ExpressionBuilder bldr = new ExpressionBuilder();
        Expression exp1 = bldr.get("firstName").equal("Bob");
        Expression exp2 = bldr.get("lastName").equal("Smith");
        Expression exp = exp1.and(exp2);

        EmployeeTLIC emp = (EmployeeTLIC)getSession().readObject(EmployeeTLIC.class, exp);

        uow1 = getSession().acquireUnitOfWork();
        uow2 = getSession().acquireUnitOfWork();
        EmployeeTLIC clone1 = (EmployeeTLIC)uow1.registerObject(emp);
        EmployeeTLIC clone2 = (EmployeeTLIC)uow2.registerObject(emp);

        clone1.getAddress().setStreet("4 Hutton Centre,Suite 900");
        clone1.getAddress().setCity("Santa Ana");
        clone1.getAddress().setProvince("CA");
        clone1.getAddress().setCountry("USA");
        clone1.getAddress().setPostalCode("92797");
        uow1.commit();

        clone2.setSalary(clone2.getSalary() + 200);
        try {
            uow2.commit();
        } catch (OptimisticLockException exception) {
            exceptionCaught = true;
        }
    }

    @Override
    protected void verify() {
        switch (testnumber) {
        case 1:
            if (!exceptionCaught)
                throw new TestErrorException("No Optimistic Lock exception was thrown");
            break;
        case 2:
        case 3:
        case 4:
            if (exceptionCaught)
                throw new TestErrorException("Optimistic Lock exception should not have been thrown");
            break;
        default:
            break;
        }
    }
}
