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

import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.testing.models.employee.domain.*;
import org.eclipse.persistence.testing.models.ownership.ObjectA;
import org.eclipse.persistence.testing.tests.writing.BidirectionalInsertTest;
import org.eclipse.persistence.testing.tests.writing.ComplexUpdateTest;
import org.eclipse.persistence.testing.tests.writing.UpdateChangeNothingTest;
import org.eclipse.persistence.testing.tests.writing.UpdateChangeObjectTest;
import org.eclipse.persistence.testing.tests.writing.UpdateChangeValueTest;
import org.eclipse.persistence.testing.tests.writing.UpdateDeepOwnershipTest;
import org.eclipse.persistence.testing.tests.writing.UpdateToNullTest;
import org.eclipse.persistence.annotations.IdValidation;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.tools.schemaframework.PopulationManager;


/**
 * Defines the main unit of work tests.
 * This suite is run under several configurations, such as three-tier and remote,
 * all tests should be compatible or throw correct warnings.
 */
public class UnitOfWorkTestSuite extends TestSuite {
    public UnitOfWorkTestSuite() {
        setDescription("This suite tests updating objects with changed parts.");
    }

    public UnitOfWorkTestSuite(boolean isSRG) {
        super(isSRG);
        setDescription("This suite tests updating objects with changed parts.");
    }

    @Override
    public void addTests() {
        addTest(new MergeCloneWithReferencesWithNullTest());
        addTest(new MergeCloneWithReferencesTransparentIndirectionTest());
        //bug 4518570
        addTest(new UnitOfWorkRevertAndResumeWithNewTest());
        //bug 4544221
        addTest(new UnitOfWorkRevertWithNewObjectTest());
        //bug 4569755
        addTest(new UnitOfWorkNullPrimaryKeyTest());
        //  Bug 294259 -  Duplicate existence checks in same UOW
        addTest(new UnitOfWorkExistingObjectsListTest());

        // Revived these tests as they were commented out with no reason given.
        addTest(new MergeUnitOfWorkTest(PopulationManager.getDefaultManager().getObject(Employee.class, "0001")));
        addTest(new RegisterationUnitOfWorkTest(PopulationManager.getDefaultManager().getObject(Employee.class,
                                                                                                "0001")));
        //addTest(new UnitOfWorkConformExceptionTest()); - Test removed as conforming exceptions moved to query level setting and no longer supported correctly.
        addTest(buildRefreshDeletedObjectTest());

        addTest(new UnregisterUnitOfWorkTest());

        // EL Bug 252047 - Mutable attributes are not cloned when isMutable is enabled on a Direct Mapping
        addTest(new CloneAttributeIfMutableTest());

        addSRGTests();

        addTest(buildRefReadOnlyTest());

        addTest(new BuildCloneFromRowOneToOneTest());

        addTest(buildCacheIndexTest());

    }

    //SRG test set is maintained by QA only, do NOT add any new tests into it.

    @Override
    public void addSRGTests() {
        PopulationManager manager = PopulationManager.getDefaultManager();
        Employee employee = (Employee)manager.getObject(Employee.class, "0001");

        // Tests with using unit of work.
        ComplexUpdateTest test = new UpdateToNullTest(employee);
        test.usesUnitOfWork = true;
        addTest(test);

        test = new UpdateChangeValueTest(employee);
        test.usesUnitOfWork = true;
        addTest(test);

        test = new UpdateChangeNothingTest(employee);
        test.usesUnitOfWork = true;
        addTest(test);

        test = new UpdateChangeObjectTest(employee);
        test.usesUnitOfWork = true;
        addTest(test);

        test = new UpdateDeepOwnershipTest((ObjectA)manager.getObject(ObjectA.class, "example1"));
        test.usesUnitOfWork = true;
        addTest(test);

        addTest(new BidirectionalInsertTest(true));
        addTest(new NestedUnitOfWorkTest(employee));
        addTest(new NestedUnitOfWorkMultipleCommitTest(employee));
        addTest(new DeepNestedUnitOfWorkTest(employee));
        addTest(new MultipleUnitOfWorkTest(employee));
        addTest(new InsertNewObjectTest());
        addTest(new ComplexMultipleUnitOfWorkTest());
        addTest(new FaultyUnitOfWorkTest());
        addTest(new LockFailureUnitOfWorkTest());
        addTest(new UnitOfWorkResumeTest(employee));
        addTest(new UnitOfWorkResumeOnFailureTest(employee));
        addTest(new DeletingFromParentSessionTest());
        addTest(new org.eclipse.persistence.testing.tests.mapping.EqualObjectUnitOfWorkTest());
        addTest(new NoIMWithValueHolderTest());
        addTest(new UnitOfWorkRevertTest(employee));
        addTest(new DeepMergeCloneSerializedTest());
        addTest(new DeepMergeCloneIndirectionTest());
        addTest(new RegisterNewObjectTest());
        addTest(new NoIdentityMapUnitOfWorkTest());
        addTest(new RefreshObjectNoIdentityMapUnitOfWorkTest());
        addTest(new RelationshipTreeInsertTest());
        addTest(new UnitOfWorkComplexRefreshTest());
        addTest(new ViolateObjectSpaceTest());
        //code coverage
        addTest(new NoValidationWithInitIdentityMaps());
        addTest(new NoIdentityTest());
        addTest(new NoIdentityMergeCloneTest());
        addTest(new org.eclipse.persistence.testing.tests.mapping.BiDirectionInsertOrderTest());
        addTest(new UnitOfWorkCommitResumeOnFailureNoFailureTest(employee));
        addTest(new UnitOfWorkCommitAndResume(employee));
        addTest(new NestedUnitOfWorkQuery());
        addTest(new DeleteAndConform());
        addTest(new NullAggregateTest());
        addTest(new UOWHasOnlyDeletesTest());
        //CR 2728
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.NULL, false, false));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.ZERO, false, false));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.NEGATIVE, false, false));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.NULL, true, false));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.ZERO, true, false));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.NEGATIVE, true, false));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.NULL, true, true));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.ZERO, true, true));
        addTest(new RegisterNewObjectInIdentityMapNoSeqTest(IdValidation.NEGATIVE, true, true));
        //CR 2783
        addTest(new NestedUnitOfWorkDeleteNewObjectTest());
        //bug 3115160
        addTest(new NestedUnitOfWorkDeleteNestedNewObjectTest());
        //bug 3132979
        addTest(new NestedUnitOfWorkDeleteConformedNestedNewObjectTest());
        addTest(new DoubleNestedUnitOfWorkDeleteConformedNestedNewObjectTest());
        //bug 3228185
        addTest(new NestedUnitOfWorkNewObjectWithIndirectionTest());

        //CR#3216
        addTest(new UnitOfWorkDeleteNoValidationTest());

        //CR 4094
        addTest(new GetIdentityMapFromUOWForREADONLYClassTest());
        //code coverage testing
        addTest(new UnitOfWorkCommitToDatabaseTest());
        addTest(new UnitOfWorkInitializeAllIdentityMapsTest());
        //CR#4204
        addTest(new WasTransactionBegunPrematurelyRollbackTest());

        //code coverage
        addTest(new CanChangeReadOnlySetTest());

        // code coverage
        addTest(new GetFromNewObjectWithConformTest());
        addTest(new UOWCommitAndResumeWithPreCalcChangeSet(employee));
        addTest(new PerformDeletesFirstTest());

        // bug 3815959
        addTest(new PerformDeletesFirstIgnoreUpdateTest());
        addTest(new PerformDeletesFirstIgnoreUpdateTest2());

        // bug 2612331
        addTest(new CreateDeleteCreateTest());
        //bug 2612602
        addTest(new WorkingCloneCopyPolicyTest());
        addTest(new UnregisteredNewObjectOptimisticLockTest());

        //bug 3510459
        addTest(new DoubleNestedUnitOfWorkRegisterNewObjectTest());

        // bug 3287196
        addTest(new GetObjectFromIdentityMapTest());

        addTest(new MergeDeadIndirectionTest());

        //Add new tests here, if any.
        addTest(new CommitAfterExecuteModifyQueryDuringTransTest());

        //bug 4364283
        addTest(new AllChangeSetsTest());

        //bug 5744009
        addTest(new CurrentChangeSetTest());

        //bug 4453001
        addTest(new ErrorOnInsertTest());

        addTest(new CollectionMappingMergeObjectTest());
        addTest(new ExceptionsRaisedUnitOfWorkTest());

        //bug 4736360
        addTest(new NestedUOWWithNewObjectRegisteredTwiceTest());

        addTest(new NestedUnitOfWorkReadOnlyClassTest());
    }

    /**
     * Test issue of loss of identity causing loop in cloning with invalidation.
     */
    public TransactionalTestCase buildRefreshDeletedObjectTest() {
        TransactionalTestCase test = new TransactionalTestCase() {
            @Override
            public void test() {
                List employees = getSession().readAllObjects(Employee.class);
                Employee employee = null;
                // Find an employee with a phone.
                for (Iterator iterator = employees.iterator(); iterator.hasNext(); ) {
                    employee = (Employee) iterator.next();
                    if (employee.getPhoneNumbers().size() > 0) {
                        break;
                    }
                }
                UnitOfWork uow = getSession().acquireUnitOfWork();
                // Delete the phone but do not remove the employee reference.
                uow.deleteObject(employee.getPhoneNumbers().get(0));
                uow.commit();
                // Invalidate the phone numbers to cause them to be refreshed.
                getSession().getIdentityMapAccessor().invalidateClass(PhoneNumber.class);
                uow = getSession().acquireUnitOfWork();
                employee = (Employee)uow.readObject(employee);
                // Trigger register of dead phone number, this cause a loop and error.
                employee.getPhoneNumbers().get(0);
                uow.commit();
            }
        };
        test.setName("RefreshDeletedObjectTest");
        test.setDescription("Test issue of loss of identity causing loop in cloning with invalidation.");
        return test;
    }

    /**
     * Tests saving a new object with a reference to a read-only object.
     */
    public TransactionalTestCase buildRefReadOnlyTest() {
        TransactionalTestCase test = new TransactionalTestCase() {
            @Override
            public void setup() {
                super.setup();
                if (getSession().isRemoteSession()) {
                    throwWarning("Test not supported on remote session.");
                }
                getSession().getDescriptor(Address.class).setReadOnly();
            }
            @Override
            public void test() {
                UnitOfWork uow = getSession().acquireUnitOfWork();
                Address address = (Address)uow.readObject(Address.class);
                Employee employee = new Employee();
                // Delete the phone but do not remove the employee reference.
                employee = (Employee)uow.registerObject(employee);
                employee.setAddress(address);
                uow.commit();
            }
            @Override
            public void reset() {
                super.reset();
                getSession().getDescriptor(Address.class).setShouldBeReadOnly(false);
            }
        };
        test.setName("RefReadOnlyTest");
        test.setDescription("Tests saving a new object with a reference to a read-only object.");
        return test;
    }

    /**
     * Tests saving a new object with a reference to a read-only object.
     */
    public TransactionalTestCase buildCacheIndexTest() {
        TransactionalTestCase test = new TransactionalTestCase() {
            @Override
            public void setup() {
                super.setup();
                if (getSession().isRemoteSession()) {
                    throwWarning("Test not supported on remote session.");
                }
            }
            @Override
            public void test() {
                QuerySQLTracker counter = new QuerySQLTracker(getSession());
                try {
                    ReadObjectQuery query = new ReadObjectQuery(Employee.class);
                    ExpressionBuilder emp = new ExpressionBuilder();
                    query.setSelectionCriteria(emp.get("firstName").equal("cache").and(emp.get("lastName").equal("index")));
                    UnitOfWork uow = getSession().acquireUnitOfWork();
                    Employee employee = new Employee();
                    employee.setFirstName("cache");
                    employee.setLastName("index");
                    employee = (Employee)uow.registerObject(employee);
                    if (uow.executeQuery(query) != null) {
                        throwError("New employee should not have been found.");
                    }
                    if (counter.getSqlStatements().size() == 0) {
                        throwError("Query should have hit database.");
                    }
                    uow.commit();
                    counter.getSqlStatements().clear();
                    if (uow.executeQuery(query) != employee) {
                        throwError("New employee should have been found.");
                    }
                    if (counter.getSqlStatements().size() > 0) {
                        throwError("Query should have hit cache.");
                    }
                    uow = getSession().acquireUnitOfWork();
                    employee = (Employee)uow.registerObject(employee);
                    employee.setLastName("fail");
                    uow.commit();
                    counter.getSqlStatements().clear();
                    if (uow.executeQuery(query) != null) {
                        throwError("Employee should not have been found.");
                    }
                    if (counter.getSqlStatements().size() == 0) {
                        throwError("Query should have hit database.");
                    }
                    query = new ReadObjectQuery(Employee.class);
                    emp = new ExpressionBuilder();
                    query.setSelectionCriteria(emp.get("firstName").equal("cache").and(emp.get("lastName").equal("fail")));
                    counter.getSqlStatements().clear();
                    if (uow.executeQuery(query) != employee) {
                        throwError("Employee should have been found.");
                    }
                    if (counter.getSqlStatements().size() > 0) {
                        throwError("Query should have hit cache.");
                    }

                } finally {
                    counter.remove();
                }
            }
        };
        test.setName("CacheIndexTest");
        test.setDescription("Tests cache indexes with new and changed objects.");
        return test;
    }

}
