/*
 * 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.io.StringWriter;
import java.io.Writer;

import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEventListener;
import org.eclipse.persistence.sessions.UnitOfWork;
import org.eclipse.persistence.testing.tests.remote.RemoteModel;
import org.eclipse.persistence.testing.framework.AutoVerifyTestCase;
import org.eclipse.persistence.testing.framework.TestErrorException;
import org.eclipse.persistence.testing.framework.TestWarningException;
import org.eclipse.persistence.testing.models.employee.domain.Employee;


/**
 * Test that the refresh in a unit of work does not needlessly commit changes.
 */
public class UnitOfWorkComplexRefreshTest extends AutoVerifyTestCase {
    protected Employee dbEmployee1;
    protected Employee dbEmployee2;
    protected UnitOfWork uow1;
    protected UnitOfWork uow2;
    protected Writer oldLog;
    protected int oldLogLevel;
    protected StringWriter tempWriter;
    // On some platforms (Sybase) if conn1 updates a row but hasn't yet committed transaction then
    // reading the row through conn2 may hang.
    // To avoid this problem the listener would decrement transaction isolation level,
    // then reading through conn2 no longer hangs, however may result (results on Sybase)
    // in reading of uncommitted data.
    SessionEventListener listener;

    public UnitOfWorkComplexRefreshTest() {
        setDescription("Test that a refreshed object in unit of work does not generate sql on commit.");
    }

    @Override
    public void setup() {
        if (getSession().isClientSession()) {
            listener = checkTransactionIsolation();
        }

        if (getSession().isRemoteSession() && getSession().getDatasourcePlatform().isDerby()) {
            throw new TestWarningException("This test uses functionality that does not work over remote sessions in Apache Derby.");
        }

        getAbstractSession().beginTransaction();
        uow1 = getSession().acquireUnitOfWork();
        uow2 = getSession().acquireUnitOfWork();

        Expression exp = new ExpressionBuilder().get("firstName").equal("Charles");
        dbEmployee1 = (Employee)uow1.readObject(Employee.class, exp);
        dbEmployee2 = (Employee)uow2.readObject(Employee.class, exp);
        dbEmployee1.getAddress().setCity("Bobstown");
    }

    @Override
    public void reset() {
        if(getAbstractSession().isInTransaction()) {
            getAbstractSession().rollbackTransaction();
        }
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
        if(listener != null) {
            getAbstractSession().getParent().getEventManager().removeListener(listener);
            listener = null;
        }
    }

    public void switchLog(Session aSession) {
        if (aSession instanceof org.eclipse.persistence.internal.sessions.remote.RemoteUnitOfWork) {
            aSession = RemoteModel.getServerSession();
        }
        oldLog = aSession.getLog();
        oldLogLevel = aSession.getLogLevel();
        aSession.setLogLevel(SessionLog.FINE);
        tempWriter = new StringWriter();
        aSession.setLog(tempWriter);
    }

    public void switchLoggingBack(Session aSession) {
        if (aSession.isRemoteUnitOfWork()) {
            aSession = RemoteModel.getServerSession();
        }
        aSession.setLogLevel(oldLogLevel);
        aSession.setLog(oldLog);
    }

    @Override
    public void test() {
        dbEmployee2.getAddress().setCity("Yousersville");
        uow2.commit();

        uow1.refreshObject(dbEmployee1);
        switchLog(uow1);
        uow1.commit();
        switchLoggingBack(uow1);
    }

    @Override
    public void verify() {
        if (dbEmployee1.getAddress().getCity().equals("Bobstown")) {
            // The address was not properly refreshed.
            throw new TestErrorException("The object in the unit of work was properly refreshed.");
        }

        if (tempWriter.toString().indexOf("UPDATE ADDRESS SET CITY = 'Yousersville'") != -1) {
            throw new TestErrorException("The second commit updated the database, but should not have, '" +
                                         tempWriter.toString() + "'");
        }
    }
}
