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

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.IsolatedClientSession;
import org.eclipse.persistence.queries.DataModifyQuery;
import org.eclipse.persistence.sessions.remote.RemoteSession;
import org.eclipse.persistence.sessions.SessionEvent;
import org.eclipse.persistence.sessions.SessionEventAdapter;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.framework.TestProblemException;
import org.eclipse.persistence.testing.framework.TestWarningException;
import org.eclipse.persistence.testing.models.employee.domain.Employee;


/*
 * Test for bug 4211104  Where query executed in UOW event (during trans) prevents UOW
 * from commiting the transaction Resulting in a rollback.
 */
public class CommitAfterExecuteModifyQueryDuringTransTest extends org.eclipse.persistence.testing.framework.AutoVerifyTestCase {
    Employee originalEmployee;
    Employee cachedEmployee = null;
    DataModifyQuery dataModifyQuery = null;
    org.eclipse.persistence.sessions.UnitOfWork uow = null;
    String employeesNewFirstName = "";
    Object initialVersionField = null;

    public CommitAfterExecuteModifyQueryDuringTransTest() {
        setDescription("Test for successful UOW commit with DataModifyQuery being executed from an event during the transaction");
    }

    /**
     * Test makes modifications that is not wrapped in a transaction..
     */
    @Override
    public void setup() {
        if (getSession() instanceof RemoteSession) {
            throw new TestWarningException("test will not run on RemoteSession - it uses events");
        }
        //employee to be modified - needed for reset.
        cachedEmployee = (Employee)getSession().readObject(Employee.class);
        ClassDescriptor descriptor = getSession().getDescriptor(this.cachedEmployee );
        if (descriptor.isProtectedIsolation() && descriptor.shouldIsolateProtectedObjectsInUnitOfWork() && getSession() instanceof IsolatedClientSession){
            // this will have read a version of the protected Entity into the Isolated Cache even though the test wants to isolated to UOW
            //replace with actual shared cache version
            this.cachedEmployee = (Employee) ((AbstractSession)getSession()).getParentIdentityMapSession(descriptor, false, true).getIdentityMapAccessor().getFromIdentityMap(this.cachedEmployee);
        }
        originalEmployee = (Employee)getSession().copy(cachedEmployee);
        employeesNewFirstName = "formerlyKnownAs";
        initialVersionField = getSession().getIdentityMapAccessor().getWriteLockValue(cachedEmployee);

        //query to be executed more than once
        dataModifyQuery =
                new DataModifyQuery("UPDATE EMPLOYEE SET F_NAME = #F_NAME, VERSION = #VERSION WHERE L_NAME = #L_NAME");
        dataModifyQuery.addArgument("F_NAME");
        dataModifyQuery.addArgument("VERSION");
        dataModifyQuery.addArgument("L_NAME");
    }

    /**
     * Test makes modifications that is not wrapped in a transaction..
     * so we have to reset our change
     */
    @Override
    public void reset() {
        Vector myV = new Vector();
        myV.addElement(originalEmployee.firstName);
        myV.addElement(initialVersionField);
        myV.addElement(originalEmployee.lastName);

        try {
            getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
            getSession().executeQuery(dataModifyQuery, myV);
        } catch (Exception internalException) {
            throw new TestProblemException("Test case may not have cleaned up correctly affecting other tests",
                                           internalException);
        }
    }

    @Override
    public void test() {
        uow = getSession().acquireUnitOfWork();
        uow.getEventManager().addListener(new SessionEventAdapter() {
                    @Override
                    public void prepareUnitOfWork(SessionEvent event) {
                        Vector myV = new Vector();
                        myV.addElement(employeesNewFirstName);
                        myV.addElement(initialVersionField);
                        myV.addElement(originalEmployee.lastName);
                        uow.executeQuery(dataModifyQuery, myV);
                    }
                });

        Employee temp = (Employee)uow.registerObject(cachedEmployee);
        temp.firstName = "tempFirstName";

        //no exceptions are expected, though transaction should not be commited if test fails:
        uow.commit();
        cachedEmployee = (Employee)getSession().refreshObject(cachedEmployee);
    }

    @Override
    public void verify() {
        if (!employeesNewFirstName.equals(cachedEmployee.firstName)) {
            throw new TestErrorException("UOW was not commited when non-selecting SQL was issued during transaction.  Emp First name was not updated");
        }
    }
}
